summaryrefslogtreecommitdiff
path: root/Build/source
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2013-02-19 00:32:39 +0000
committerKhaled Hosny <khaledhosny@eglug.org>2013-02-19 00:32:39 +0000
commitb9a5b9cad6d163192c3ab462fc86adc525a81e71 (patch)
tree11f84a8fdd80d31f9e49565a2e75a4e782146308 /Build/source
parente43ae240f33296136cb498e6d9d0e9a55eba7493 (diff)
Sync with XeTeX
git-svn-id: svn://tug.org/texlive/trunk@29157 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source')
-rw-r--r--Build/source/texk/web2c/xetexdir/FontTableCache.cpp2
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp6
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontInst.h4
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp107
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h7
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp6
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h27
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h11
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm234
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp147
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h69
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp6
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeX_ext.c773
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeX_ext.h158
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeX_mac.c1238
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeX_pic.c2
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXswap.h28
-rw-r--r--Build/source/texk/web2c/xetexdir/am/xetex.am2
-rw-r--r--Build/source/texk/web2c/xetexdir/pdfimage.cpp6
-rw-r--r--Build/source/texk/web2c/xetexdir/trans.c25
-rw-r--r--Build/source/texk/web2c/xetexdir/trans.h17
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.defines2
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.h6
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.web52
-rw-r--r--Build/source/texk/web2c/xetexdir/xetexwebmac.tex255
25 files changed, 1461 insertions, 1729 deletions
diff --git a/Build/source/texk/web2c/xetexdir/FontTableCache.cpp b/Build/source/texk/web2c/xetexdir/FontTableCache.cpp
index d8d3ed54714..48b0520aed7 100644
--- a/Build/source/texk/web2c/xetexdir/FontTableCache.cpp
+++ b/Build/source/texk/web2c/xetexdir/FontTableCache.cpp
@@ -60,7 +60,7 @@ FontTableCache::FontTableCache()
void
FontTableCache::initialize()
{
- fTableCache = (FontTableCacheEntry *) malloc((fTableCacheSize) * sizeof(FontTableCacheEntry));
+ fTableCache = (FontTableCacheEntry *) xmalloc((fTableCacheSize) * sizeof(FontTableCacheEntry));
if (fTableCache == NULL) {
fTableCacheSize = 0;
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp
index 2013c442e2b..837640d1d48 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp
@@ -43,10 +43,6 @@ authorization from the copyright holders.
#include "XeTeXLayoutInterface.h"
#include "XeTeXswap.h"
-#ifdef XETEX_MAC
-#include <Carbon/Carbon.h>
-#endif
-
#include "XeTeX_ext.h"
#include "sfnt.h"
@@ -118,7 +114,7 @@ void XeTeXFontInst::initialize(int &status)
postTable = (const POSTTable *) readFontTable(kPOST);
if (postTable != NULL) {
- fItalicAngle = Fix2D(SWAP(UInt32(postTable->italicAngle)));
+ fItalicAngle = Fix2D(SWAP(uint32_t(postTable->italicAngle)));
deleteTable(postTable);
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h
index 3c49bccc126..811c8d53bb2 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h
@@ -52,10 +52,6 @@ authorization from the copyright holders.
#include "XeTeXFontMgr.h"
#include "XeTeX_ext.h"
-extern "C" {
- void *xmalloc(size_t); // from kpathsea
-};
-
// create specific subclasses for each supported platform
class XeTeXFontInst : protected FontTableCache
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp
index 5a4c26e15d9..741ab5be0f3 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp
@@ -2,6 +2,8 @@
Part of the XeTeX typesetting system
Copyright (c) 1994-2008 by SIL International
Copyright (c) 2009 by Jonathan Kew
+ Copyright (c) 2012, 2013 by Jiang Jiang
+ Copyright (c) 2012, 2013 by Khaled Hosny
SIL Author(s): Jonathan Kew
@@ -41,10 +43,10 @@ authorization from the copyright holders.
#include "XeTeXFontInst_Mac.h"
#include "XeTeX_ext.h"
-XeTeXFontInst_Mac::XeTeXFontInst_Mac(ATSFontRef atsFont, float pointSize, int &status)
+XeTeXFontInst_Mac::XeTeXFontInst_Mac(CTFontDescriptorRef descriptor, float pointSize, int &status)
: XeTeXFontInst(pointSize, status)
- , fFontRef(atsFont)
- , fStyle(0)
+ , fDescriptor(descriptor)
+ , fFontRef(0)
, fFirstCharCode(-1)
, fLastCharCode(-1)
{
@@ -57,26 +59,36 @@ XeTeXFontInst_Mac::XeTeXFontInst_Mac(ATSFontRef atsFont, float pointSize, int &s
XeTeXFontInst_Mac::~XeTeXFontInst_Mac()
{
- if (fStyle != 0)
- ATSUDisposeStyle(fStyle);
+ if (fDescriptor != 0)
+ CFRelease(fDescriptor);
+ if (fFontRef != 0)
+ CFRelease(fFontRef);
}
-static hb_bool_t _get_glyph(hb_font_t* hbFont, void* fontData, hb_codepoint_t unicode, hb_codepoint_t variationSelector, hb_codepoint_t* glyph, void* userData)
+static hb_bool_t _get_glyph(hb_font_t*, void* font, hb_codepoint_t ch, hb_codepoint_t vs, hb_codepoint_t* glyph, void*)
{
- *glyph = MapCharToGlyph_AAT((ATSUStyle) fontData, unicode);
+ *glyph = mapCharToGlyphFromCTFont((CTFontRef) font, ch, vs);
return !!glyph;
}
-static hb_position_t _get_glyph_h_advance(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, void* userData)
+static hb_position_t _get_glyph_h_advance(hb_font_t*, void* font, hb_codepoint_t glyph, void*)
{
- float width = GetGlyphWidth_AAT((ATSUStyle) fontData, glyph);
- return width * 64;
+ CGGlyph cgGlyph = glyph;
+ float advance = CTFontGetAdvancesForGlyphs((CTFontRef) font, kCTFontHorizontalOrientation, &cgGlyph, 0, 1);
+ return advance * 64;
}
-static hb_bool_t _get_glyph_extents(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, hb_glyph_extents_t* extents, void* userData)
+static hb_position_t _get_glyph_v_advance(hb_font_t*, void* font, hb_codepoint_t glyph, void*)
+{
+ CGGlyph cgGlyph = glyph;
+ float advance = CTFontGetAdvancesForGlyphs((CTFontRef) font, kCTFontVerticalOrientation, &cgGlyph, 0, 1);
+ return advance * 64;
+}
+
+static hb_bool_t _get_glyph_extents(hb_font_t*, void* font, hb_codepoint_t glyph, hb_glyph_extents_t* extents, void*)
{
GlyphBBox bbox;
- GetGlyphBBox_AAT((ATSUStyle) fontData, glyph, &bbox);
+ getGlyphBBoxFromCTFont((CTFontRef) font, glyph, &bbox);
extents->x_bearing = bbox.xMin;
extents->y_bearing = bbox.yMax;
extents->width = bbox.xMax - bbox.xMin;
@@ -91,13 +103,14 @@ static hb_font_funcs_t* _get_font_funcs()
_font_funcs = hb_font_funcs_create();
hb_font_funcs_set_glyph_func(_font_funcs, _get_glyph, 0, 0);
hb_font_funcs_set_glyph_h_advance_func(_font_funcs, _get_glyph_h_advance, 0, 0);
+ hb_font_funcs_set_glyph_v_advance_func(_font_funcs, _get_glyph_v_advance, 0, 0);
hb_font_funcs_set_glyph_extents_func(_font_funcs, _get_glyph_extents, 0, 0);
hb_font_funcs_make_immutable(_font_funcs);
return _font_funcs;
}
-static hb_blob_t* _get_font_table(hb_face_t* face, hb_tag_t tag, void* userData)
+static hb_blob_t* _get_font_table(hb_face_t*, hb_tag_t tag, void* userData)
{
XeTeXFontInst* font = (XeTeXFontInst*) userData;
uint32_t length;
@@ -109,70 +122,72 @@ static hb_blob_t* _get_font_table(hb_face_t* face, hb_tag_t tag, void* userData)
void XeTeXFontInst_Mac::initialize(int &status)
{
- if (fFontRef == 0) {
+ if (fDescriptor == 0) {
status = 1;
return;
}
- XeTeXFontInst::initialize(status);
-
if (status != 0)
- fFontRef = 0;
-
- if (ATSUCreateStyle(&fStyle) == noErr) {
- ATSUFontID font = FMGetFontFromATSFontRef(fFontRef);
- Fixed size = D2Fix(fPointSize * 72.0 / 72.27); /* convert TeX to Quartz points */
- ATSStyleRenderingOptions options = kATSStyleNoHinting;
- ATSUAttributeTag tags[3] = { kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag };
- ByteCount valueSizes[3] = { sizeof(ATSUFontID), sizeof(Fixed), sizeof(ATSStyleRenderingOptions) };
- ATSUAttributeValuePtr values[3] = { &font, &size, &options };
- ATSUSetAttributes(fStyle, 3, tags, valueSizes, values);
+ fDescriptor = 0;
+
+ // Create a copy of original font descriptor with font cascading (fallback) disabled
+ CFArrayRef emptyCascadeList = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
+ const void* values[] = { emptyCascadeList };
+ static const void* attributeKeys[] = { kCTFontCascadeListAttribute };
+ CFDictionaryRef attributes = CFDictionaryCreate(NULL, attributeKeys, values, 1,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(emptyCascadeList);
+
+ fDescriptor = CTFontDescriptorCreateCopyWithAttributes(fDescriptor, attributes);
+ CFRelease(attributes);
+ fFontRef = CTFontCreateWithFontDescriptor(fDescriptor, fPointSize * 72.0 / 72.27, NULL);
+ if (fFontRef) {
+ fFilename = getFileNameFromCTFont(fFontRef);
/* for HarfBuzz */
hb_face_t* lFace = hb_face_create_for_tables(_get_font_table, this, 0);
hb_face_set_upem (lFace, fUnitsPerEM);
hbFont = hb_font_create(lFace);
- hb_font_set_funcs(hbFont, _get_font_funcs(), fStyle, 0);
+ hb_font_set_funcs(hbFont, _get_font_funcs(), (void*) fFontRef, 0);
hb_font_set_scale(hbFont, fPointSize, fPointSize);
hb_font_set_ppem(hbFont, fPointSize, fPointSize);
- }
- else {
+ } else {
status = 1;
- fFontRef = 0;
+ CFRelease(fDescriptor);
+ fDescriptor = 0;
}
- return;
+ XeTeXFontInst::initialize(status);
}
const void *XeTeXFontInst_Mac::readTable(OTTag tag, uint32_t *length) const
{
- OSStatus status = ATSFontGetTable(fFontRef, tag, 0, 0, 0, (ByteCount*)length);
- if (status != noErr) {
+ if (!fFontRef) {
*length = 0;
return NULL;
}
- void* table = xmalloc(*length * sizeof(char));
- if (table != NULL) {
- status = ATSFontGetTable(fFontRef, tag, 0, *length, table, (ByteCount*)length);
- if (status != noErr) {
- *length = 0;
- free((void*) table);
- return NULL;
- }
+ CFDataRef tableData = CTFontCopyTable(fFontRef, tag, 0);
+ if (!tableData) {
+ *length = 0;
+ return NULL;
}
+ *length = CFDataGetLength(tableData);
+ UInt8* table = (UInt8*) xmalloc(*length * sizeof(UInt8));
+ if (table != NULL)
+ CFDataGetBytes(tableData, CFRangeMake(0, *length), table);
- return table;
+ return table;
}
void XeTeXFontInst_Mac::getGlyphBounds(GlyphID gid, GlyphBBox* bbox)
{
- GetGlyphBBox_AAT(fStyle, gid, bbox);
+ getGlyphBBoxFromCTFont(fFontRef, gid, bbox);
}
GlyphID
XeTeXFontInst_Mac::mapCharToGlyph(UChar32 ch) const
{
- return MapCharToGlyph_AAT(fStyle, ch);
+ return mapCharToGlyphFromCTFont(fFontRef, ch, 0);
}
GlyphID
@@ -181,7 +196,7 @@ XeTeXFontInst_Mac::mapGlyphToIndex(const char* glyphName) const
GlyphID rval = XeTeXFontInst::mapGlyphToIndex(glyphName);
if (rval)
return rval;
- return GetGlyphIDFromCGFont(fFontRef, glyphName);
+ return GetGlyphIDFromCTFont(fFontRef, glyphName);
}
const char*
@@ -190,7 +205,7 @@ XeTeXFontInst_Mac::getGlyphName(GlyphID gid, int& nameLen)
const char* rval = XeTeXFontInst::getGlyphName(gid, nameLen);
if (rval)
return rval;
- return GetGlyphNameFromCGFont(fFontRef, gid, &nameLen);
+ return GetGlyphNameFromCTFont(fFontRef, gid, &nameLen);
}
UChar32
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h
index e3ab7bce439..f0c41ac4ac5 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h
@@ -2,6 +2,7 @@
Part of the XeTeX typesetting system
Copyright (c) 1994-2008 by SIL International
Copyright (c) 2009 by Jonathan Kew
+ Copyright (c) 2012, 2013 by Jiang Jiang
SIL Author(s): Jonathan Kew
@@ -50,14 +51,14 @@ class XeTeXFontInst_Mac : public XeTeXFontInst
protected:
const void *readTable(OTTag tag, uint32_t *length) const;
- ATSFontRef fFontRef;
- ATSUStyle fStyle;
+ CTFontDescriptorRef fDescriptor;
+ CTFontRef fFontRef;
int fFirstCharCode;
int fLastCharCode;
public:
- XeTeXFontInst_Mac(ATSFontRef atsFont, float pointSize, int &status);
+ XeTeXFontInst_Mac(CTFontDescriptorRef descriptor, float pointSize, int &status);
virtual ~XeTeXFontInst_Mac();
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp
index 3521a6b9b35..f07de6aedc3 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp
@@ -519,7 +519,7 @@ XeTeXFontMgr::getOpSizeRecAndStyleFlags(Font* theFont)
if (os2Table != NULL) {
theFont->weight = SWAP(os2Table->usWeightClass);
theFont->width = SWAP(os2Table->usWidthClass);
- UInt16 sel = SWAP(os2Table->fsSelection);
+ uint16_t sel = SWAP(os2Table->fsSelection);
theFont->isReg = (sel & (1 << 6)) != 0;
theFont->isBold = (sel & (1 << 5)) != 0;
theFont->isItalic = (sel & (1 << 0)) != 0;
@@ -527,7 +527,7 @@ XeTeXFontMgr::getOpSizeRecAndStyleFlags(Font* theFont)
const HEADTable* headTable = (const HEADTable*)getFontTablePtr(font, kHEAD);
if (headTable != NULL) {
- UInt16 ms = SWAP(headTable->macStyle);
+ uint16_t ms = SWAP(headTable->macStyle);
if ((ms & (1 << 0)) != 0)
theFont->isBold = true;
if ((ms & (1 << 1)) != 0)
@@ -536,7 +536,7 @@ XeTeXFontMgr::getOpSizeRecAndStyleFlags(Font* theFont)
const POSTTable* postTable = (const POSTTable*)getFontTablePtr(font, kPOST);
if (postTable != NULL) {
- theFont->slant = (int)(1000 * (tan(Fix2D(-SWAP(UInt32(postTable->italicAngle))) * M_PI / 180.0)));
+ theFont->slant = (int)(1000 * (tan(Fix2D(-SWAP(uint32_t(postTable->italicAngle))) * M_PI / 180.0)));
}
deleteFont(font);
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h
index 358d540ad0b..941e30d4d4e 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h
@@ -2,6 +2,7 @@
Part of the XeTeX typesetting system
Copyright (c) 1994-2008 by SIL International
Copyright (c) 2009 by Jonathan Kew
+ Copyright (c) 2012, 2013 by Jiang Jiang
SIL Author(s): Jonathan Kew
@@ -34,8 +35,8 @@ authorization from the copyright holders.
#define __XETEX_FONT_MANAGER_H
#ifdef XETEX_MAC
-#include <Carbon/Carbon.h>
-typedef ATSFontRef PlatformFontRef;
+#include <ApplicationServices/ApplicationServices.h>
+typedef CTFontDescriptorRef PlatformFontRef;
#else
#include <fontconfig/fontconfig.h>
#include <ft2build.h>
@@ -140,9 +141,9 @@ protected:
Family* parent;
PlatformFontRef fontRef;
OpSizeRec opSizeInfo;
- UInt16 weight;
- UInt16 width;
- SInt16 slant;
+ uint16_t weight;
+ uint16_t width;
+ int16_t slant;
bool isReg;
bool isBold;
bool isItalic;
@@ -163,12 +164,12 @@ protected:
}
std::map<std::string,Font*>* styles;
- UInt16 minWeight;
- UInt16 maxWeight;
- UInt16 minWidth;
- UInt16 maxWidth;
- SInt16 minSlant;
- SInt16 maxSlant;
+ uint16_t minWeight;
+ uint16_t maxWeight;
+ uint16_t minWidth;
+ uint16_t maxWidth;
+ int16_t minSlant;
+ int16_t maxSlant;
};
class NameCollection {
@@ -197,11 +198,7 @@ protected:
virtual void getOpSizeRecAndStyleFlags(Font* theFont);
virtual void searchForHostPlatformFonts(const std::string& name) = 0;
-#ifdef XETEX_MAC
- virtual NameCollection* readNames(ATSUFontID fontID) = 0;
-#else
virtual NameCollection* readNames(PlatformFontRef fontRef) = 0;
-#endif
void die(const char*s, int i) const; /* for fatal internal errors! */
};
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h
index 7adbe97a4ee..fe19cef7c97 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h
@@ -2,6 +2,7 @@
Part of the XeTeX typesetting system
Copyright (c) 1994-2008 by SIL International
Copyright (c) 2009 by Jonathan Kew
+ Copyright (c) 2012, 2013 by Jiang Jiang
SIL Author(s): Jonathan Kew
@@ -53,16 +54,20 @@ protected:
virtual void searchForHostPlatformFonts(const std::string& name);
- virtual NameCollection* readNames(ATSUFontID fontID);
+ virtual NameCollection* readNames(CTFontDescriptorRef fontRef);
virtual std::string getPlatformFontDesc(PlatformFontRef font) const;
private:
void addFontsToCaches(CFArrayRef fonts);
- void addFamilyToCaches(ATSFontFamilyRef familyRef);
+ void addFamilyToCaches(CTFontDescriptorRef familyRef);
- void addFontAndSiblingsToCaches(ATSFontRef fontRef);
+ void addFontAndSiblingsToCaches(CTFontDescriptorRef fontRef);
+
+ void appendNameToList(CTFontRef font,
+ std::list<std::string>* nameList,
+ CFStringRef nameKey);
};
#endif /* __XETEX_FONT_MGR_MAC_H */
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm
index bcc122adf01..a1b997c0573 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm
@@ -2,6 +2,7 @@
Part of the XeTeX typesetting system
Copyright (c) 1994-2008 by SIL International
Copyright (c) 2009 by Jonathan Kew
+ Copyright (c) 2012, 2013 by Jiang Jiang
SIL Author(s): Jonathan Kew
@@ -36,133 +37,70 @@ authorization from the copyright holders.
#include <Cocoa/Cocoa.h>
-XeTeXFontMgr::NameCollection*
-XeTeXFontMgr_Mac::readNames(ATSFontRef fontRef)
+CTFontDescriptorRef findFontWithName(CFStringRef name, CFStringRef key)
{
- const int BUFUNIT = 256;
- static int bufSize = BUFUNIT;
- static char* buffer = new char[bufSize];
+ CFStringRef keys[] = { key };
+ CFTypeRef values[] = { name };
+ CFDictionaryRef attributes = CFDictionaryCreate(NULL, (const void **) &keys, (const void **) &values, 1,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+ CFRelease(attributes);
+
+ CFSetRef mandatoryAttributes = CFSetCreate(NULL, (const void **) &keys, 1, &kCFTypeSetCallBacks);
+ CFArrayRef matches = CTFontDescriptorCreateMatchingFontDescriptors(descriptor, mandatoryAttributes);
+ CFRelease(mandatoryAttributes);
+ CFRelease(descriptor);
+
+ CTFontDescriptorRef matched = NULL;
+ if (matches) {
+ if (CFArrayGetCount(matches)) {
+ matched = (CTFontDescriptorRef) CFArrayGetValueAtIndex(matches, 0);
+ CFRetain(matched);
+ }
+ CFRelease(matches);
+ }
+ return matched;
+}
+
+void
+XeTeXFontMgr_Mac::appendNameToList(CTFontRef font,
+ std::list<std::string>* nameList,
+ CFStringRef nameKey)
+{
+ CFStringRef name = CTFontCopyName(font, nameKey);
+ if (name) {
+ appendToList(nameList, [(NSString *) name UTF8String]);
+ CFRelease(name);
+ }
+ CFStringRef language;
+ name = CTFontCopyLocalizedName(font, nameKey, &language);
+ if (name) {
+ appendToList(nameList, [(NSString *) name UTF8String]);
+ CFRelease(name);
+ }
+}
+XeTeXFontMgr::NameCollection*
+XeTeXFontMgr_Mac::readNames(CTFontDescriptorRef fontRef)
+{
NameCollection* names = new NameCollection;
- CFStringRef psName;
- OSStatus status = ATSFontGetPostScriptName(fontRef, kATSOptionFlagsDefault, &psName);
- if (status != noErr)
+ CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(fontRef, kCTFontNameAttribute);
+ if (!psName)
return names;
-
- // extract UTF-8 form of name
- CFIndex length = CFStringGetLength(psName); // in 16-bit character units
- if (length > 0) {
- length = length * 6 + 1;
- if (length >= bufSize) {
- delete[] buffer;
- bufSize = ((length / BUFUNIT) + 1) * BUFUNIT;
- buffer = new char[bufSize];
- }
- if (CFStringGetCString(psName, buffer, bufSize, kCFStringEncodingUTF8))
- names->psName = buffer;
- }
+
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+
+ names->psName = [(NSString *) psName UTF8String];
CFRelease(psName);
- ATSUFontID fontID = FMGetFontFromATSFontRef(fontRef);
-
- ItemCount nameCount;
- status = ATSUCountFontNames(fontID, &nameCount);
- if (status != noErr)
- die("ATSUCountFontNames failed, status=%d", status);
-
- std::list<std::string> familyNames;
- std::list<std::string> subFamilyNames;
-
- for (int n = 0; n < nameCount; ++n) {
- ByteCount nameLength;
- FontNameCode nameCode;
- FontPlatformCode namePlatform;
- FontScriptCode nameScript;
- FontLanguageCode nameLang;
- status = ATSUGetIndFontName(fontID, n, 0, 0, &nameLength,
- &nameCode, &namePlatform, &nameScript, &nameLang);
- if (status != noErr && status != kATSUNoFontNameErr)
- die("ATSUGetIndFontName failed, status=%d", status);
- if (status == noErr && nameLength > 0) {
- switch (nameCode) {
- case kFontFullName:
- case kFontFamilyName:
- case kFontStyleName:
- case 16: // preferred family -- use instead of family, if present
- case 17: // preferred subfamily -- use instead of style, if present
- {
- bool preferredName = false;
- TextEncoding encoding;
- CFStringRef nameStr = 0;
- if (nameLength >= bufSize) {
- delete[] buffer;
- bufSize = ((nameLength / BUFUNIT) + 1) * BUFUNIT;
- buffer = new char[bufSize];
- }
- status = ATSUGetIndFontName(fontID, n, bufSize, buffer, &nameLength,
- &nameCode, &namePlatform, &nameScript, &nameLang);
- if (namePlatform == kFontMacintoshPlatform) {
- GetTextEncodingFromScriptInfo(nameScript, nameLang, 0, &encoding);
- nameStr = CFStringCreateWithBytes(0, (UInt8*)buffer, nameLength, encoding, false);
- if (nameScript == kFontRomanScript && nameLang == kFontEnglishLanguage)
- preferredName = true;
- }
- else if ((namePlatform == kFontUnicodePlatform) || (namePlatform == kFontMicrosoftPlatform))
- nameStr = CFStringCreateWithCharacters(0, (UniChar*)buffer, nameLength / 2);
- if (nameStr != 0) {
- std::list<std::string>* nameList = NULL;
- switch (nameCode) {
- case kFontFullName:
- nameList = &names->fullNames;
- break;
- case kFontFamilyName:
- nameList = &names->familyNames;
- break;
- case kFontStyleName:
- nameList = &names->styleNames;
- break;
- case 16:
- nameList = &familyNames;
- break;
- case 17:
- nameList = &subFamilyNames;
- break;
- }
-
- // extract UTF-8 form of name
- length = CFStringGetLength(nameStr); // in 16-bit character units
- if (length > 0) {
- length = length * 6 + 1;
- if (length >= bufSize) {
- delete[] buffer;
- bufSize = ((length / BUFUNIT) + 1) * BUFUNIT;
- buffer = new char[bufSize];
- }
- if (CFStringGetCString(nameStr, buffer, bufSize, kCFStringEncodingUTF8)) {
- if (buffer[0] != 0) {
- if (nameList != NULL) {
- if (preferredName)
- prependToList(nameList, buffer);
- else
- appendToList(nameList, buffer);
- }
- }
- }
- }
-
- CFRelease(nameStr);
- }
- }
- break;
- }
- }
- }
+ CTFontRef font = CTFontCreateWithFontDescriptor(fontRef, 0.0, 0);
+ appendNameToList(font, &names->fullNames, kCTFontFullNameKey);
+ appendNameToList(font, &names->familyNames, kCTFontFamilyNameKey);
+ appendNameToList(font, &names->styleNames, kCTFontStyleNameKey);
+ CFRelease(font);
- if (familyNames.size() > 0)
- names->familyNames = familyNames;
- if (subFamilyNames.size() > 0)
- names->styleNames = subFamilyNames;
+ [pool release];
return names;
}
@@ -172,7 +110,7 @@ XeTeXFontMgr_Mac::addFontsToCaches(CFArrayRef fonts)
{
NSEnumerator* enumerator = [(NSArray*)fonts objectEnumerator];
while (id aFont = [enumerator nextObject]) {
- ATSFontRef fontRef = ATSFontFindFromPostScriptName((CFStringRef)[aFont objectAtIndex: 0], kATSOptionFlagsDefault);
+ CTFontDescriptorRef fontRef = findFontWithName((CFStringRef)[aFont objectAtIndex: 0], kCTFontNameAttribute);
NameCollection* names = readNames(fontRef);
addToMaps(fontRef, names);
delete names;
@@ -180,11 +118,10 @@ XeTeXFontMgr_Mac::addFontsToCaches(CFArrayRef fonts)
}
void
-XeTeXFontMgr_Mac::addFamilyToCaches(ATSFontFamilyRef familyRef)
+XeTeXFontMgr_Mac::addFamilyToCaches(CTFontDescriptorRef familyRef)
{
- CFStringRef nameStr;
- OSStatus status = ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &nameStr);
- if (status == noErr) {
+ CFStringRef nameStr = (CFStringRef) CTFontDescriptorCopyAttribute(familyRef, kCTFontFamilyNameAttribute);
+ if (nameStr) {
NSArray* members = [[NSFontManager sharedFontManager]
availableMembersOfFontFamily: (NSString*)nameStr];
CFRelease(nameStr);
@@ -193,11 +130,10 @@ XeTeXFontMgr_Mac::addFamilyToCaches(ATSFontFamilyRef familyRef)
}
void
-XeTeXFontMgr_Mac::addFontAndSiblingsToCaches(ATSFontRef fontRef)
+XeTeXFontMgr_Mac::addFontAndSiblingsToCaches(CTFontDescriptorRef fontRef)
{
- CFStringRef name;
- OSStatus status = ATSFontGetPostScriptName(fontRef, kATSOptionFlagsDefault, &name);
- if (status == noErr) {
+ CFStringRef name = (CFStringRef) CTFontDescriptorCopyAttribute(fontRef, kCTFontNameAttribute);
+ if (name) {
NSFont* font = [NSFont fontWithName:(NSString*)name size:10.0];
CFRelease(name);
NSArray* members = [[NSFontManager sharedFontManager]
@@ -217,10 +153,11 @@ XeTeXFontMgr_Mac::searchForHostPlatformFonts(const std::string& name)
// ...so we need to try it as each of these
CFStringRef nameStr = CFStringCreateWithCString(kCFAllocatorDefault, name.c_str(), kCFStringEncodingUTF8);
- ATSFontRef fontRef = ATSFontFindFromName(nameStr, kATSOptionFlagsDefault);
- if (fontRef != kATSFontRefUnspecified) {
+ CTFontDescriptorRef matched = findFontWithName(nameStr, kCTFontDisplayNameAttribute);
+ if (matched) {
// found it, so locate the family, and add all members to the caches
- addFontAndSiblingsToCaches(fontRef);
+ addFontAndSiblingsToCaches(matched);
+ CFRelease(matched);
return;
}
@@ -236,16 +173,18 @@ XeTeXFontMgr_Mac::searchForHostPlatformFonts(const std::string& name)
return;
}
- ATSFontFamilyRef familyRef = ATSFontFamilyFindFromName(familyStr, kATSOptionFlagsDefault);
- if (familyRef != 0xffffffff) {
- addFamilyToCaches(familyRef);
+ matched = findFontWithName(familyStr, kCTFontFamilyNameAttribute);
+ if (matched) {
+ addFamilyToCaches(matched);
+ CFRelease(matched);
return;
}
}
- fontRef = ATSFontFindFromPostScriptName(nameStr, kATSOptionFlagsDefault);
- if (fontRef != kATSFontRefUnspecified) {
- addFontAndSiblingsToCaches(fontRef);
+ matched = findFontWithName(nameStr, kCTFontNameAttribute);
+ if (matched) {
+ addFontAndSiblingsToCaches(matched);
+ CFRelease(matched);
return;
}
@@ -256,9 +195,10 @@ XeTeXFontMgr_Mac::searchForHostPlatformFonts(const std::string& name)
return;
}
- ATSFontFamilyRef familyRef = ATSFontFamilyFindFromName(nameStr, kATSOptionFlagsDefault);
- if (familyRef != 0xffffffff) {
- addFamilyToCaches(familyRef);
+ matched = findFontWithName(nameStr, kCTFontFamilyNameAttribute);
+ if (matched) {
+ addFamilyToCaches(matched);
+ CFRelease(matched);
return;
}
}
@@ -280,18 +220,20 @@ XeTeXFontMgr_Mac::terminate()
}
std::string
-XeTeXFontMgr_Mac::getPlatformFontDesc(PlatformFontRef font) const
+XeTeXFontMgr_Mac::getPlatformFontDesc(PlatformFontRef descriptor) const
{
- FSSpec fileSpec;
std::string path;
- if (ATSFontGetFileSpecification(font, &fileSpec) == noErr) {
- FSRef fileRef;
- if (FSpMakeFSRef(&fileSpec, &fileRef) == noErr) {
+ CTFontRef ctFont = CTFontCreateWithFontDescriptor(descriptor, 0.0, 0);
+ if (ctFont) {
+ CFURLRef url = (CFURLRef) CTFontCopyAttribute(ctFont, kCTFontURLAttribute);
+ if (url) {
UInt8 posixPath[PATH_MAX];
- if (FSRefMakePath(&fileRef, posixPath, PATH_MAX) == noErr) {
+ if (CFURLGetFileSystemRepresentation(url, true, posixPath, PATH_MAX)) {
path = (char*)posixPath;
}
+ CFRelease(url);
}
+ CFRelease(ctFont);
}
if (path.length() == 0)
path = "[unknown]";
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp
index dd0509c29a4..4920d321d9b 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp
@@ -54,7 +54,7 @@ struct XeTeXLayoutEngine_rec
char** ShaperList; // the requested shapers
char* shaper; // the actually used shaper
int nFeatures;
- UInt32 rgbValue;
+ uint32_t rgbValue;
float extend;
float slant;
float embolden;
@@ -68,13 +68,13 @@ struct XeTeXLayoutEngine_rec
// key is combined value representing (font_id << 16) + glyph
// value is glyph bounding box in TeX points
-static std::map<UInt32,GlyphBBox> sGlyphBoxes;
+static std::map<uint32_t,GlyphBBox> sGlyphBoxes;
int
-getCachedGlyphBBox(UInt16 fontID, UInt16 glyphID, GlyphBBox* bbox)
+getCachedGlyphBBox(uint16_t fontID, uint16_t glyphID, GlyphBBox* bbox)
{
- UInt32 key = ((UInt32)fontID << 16) + glyphID;
- std::map<UInt32,GlyphBBox>::const_iterator i = sGlyphBoxes.find(key);
+ uint32_t key = ((uint32_t)fontID << 16) + glyphID;
+ std::map<uint32_t,GlyphBBox>::const_iterator i = sGlyphBoxes.find(key);
if (i == sGlyphBoxes.end()) {
return 0;
}
@@ -83,9 +83,9 @@ getCachedGlyphBBox(UInt16 fontID, UInt16 glyphID, GlyphBBox* bbox)
}
void
-cacheGlyphBBox(UInt16 fontID, UInt16 glyphID, const GlyphBBox* bbox)
+cacheGlyphBBox(uint16_t fontID, uint16_t glyphID, const GlyphBBox* bbox)
{
- UInt32 key = ((UInt32)fontID << 16) + glyphID;
+ uint32_t key = ((uint32_t)fontID << 16) + glyphID;
sGlyphBoxes[key] = *bbox;
}
/*******************************************************************/
@@ -99,7 +99,7 @@ XeTeXFont createFont(PlatformFontRef fontRef, Fixed pointSize)
{
int status = 0;
#ifdef XETEX_MAC
- XeTeXFontInst* font = new XeTeXFontInst_Mac((ATSFontRef)fontRef, Fix2D(pointSize), status);
+ XeTeXFontInst* font = new XeTeXFontInst_Mac(fontRef, Fix2D(pointSize), status);
#else
FcChar8* pathname = 0;
FcPatternGetString(fontRef, FC_FILE, 0, &pathname);
@@ -175,7 +175,7 @@ void deleteFont(XeTeXFont font)
delete (XeTeXFontInst*)font;
}
-void* getFontTablePtr(XeTeXFont font, UInt32 tableTag)
+void* getFontTablePtr(XeTeXFont font, uint32_t tableTag)
{
return const_cast<void*>(((XeTeXFontInst*)font)->getFontTable(tableTag));
}
@@ -186,7 +186,7 @@ Fixed getSlant(XeTeXFont font)
return D2Fix(tan(-italAngle * M_PI / 180.0));
}
-static UInt32
+static uint32_t
getLargerScriptListTable(XeTeXFont font, hb_tag_t** scriptList, hb_tag_t* tableTag)
{
hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont);
@@ -217,16 +217,16 @@ getLargerScriptListTable(XeTeXFont font, hb_tag_t** scriptList, hb_tag_t* tableT
}
}
-UInt32 countScripts(XeTeXFont font)
+uint32_t countScripts(XeTeXFont font)
{
return getLargerScriptListTable(font, NULL, NULL);
}
-UInt32 getIndScript(XeTeXFont font, UInt32 index)
+uint32_t getIndScript(XeTeXFont font, uint32_t index)
{
hb_tag_t* scriptList;
- UInt32 scriptCount = getLargerScriptListTable(font, &scriptList, NULL);
+ uint32_t scriptCount = getLargerScriptListTable(font, &scriptList, NULL);
if (scriptList == NULL)
return 0;
@@ -236,13 +236,13 @@ UInt32 getIndScript(XeTeXFont font, UInt32 index)
return 0;
}
-UInt32 countScriptLanguages(XeTeXFont font, UInt32 script)
+uint32_t countScriptLanguages(XeTeXFont font, uint32_t script)
{
hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont);
hb_tag_t* scriptList;
hb_tag_t tableTag;
- UInt32 scriptCount = getLargerScriptListTable(font, &scriptList, &tableTag);
+ uint32_t scriptCount = getLargerScriptListTable(font, &scriptList, &tableTag);
if (scriptList == NULL)
return 0;
@@ -254,13 +254,13 @@ UInt32 countScriptLanguages(XeTeXFont font, UInt32 script)
return 0;
}
-UInt32 getIndScriptLanguage(XeTeXFont font, UInt32 script, UInt32 index)
+uint32_t getIndScriptLanguage(XeTeXFont font, uint32_t script, uint32_t index)
{
hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont);
hb_tag_t* scriptList;
hb_tag_t tableTag;
- UInt32 scriptCount = getLargerScriptListTable(font, &scriptList, &tableTag);
+ uint32_t scriptCount = getLargerScriptListTable(font, &scriptList, &tableTag);
if (scriptList == NULL)
return 0;
@@ -279,10 +279,10 @@ UInt32 getIndScriptLanguage(XeTeXFont font, UInt32 script, UInt32 index)
return 0;
}
-UInt32 countFeatures(XeTeXFont font, UInt32 script, UInt32 language)
+uint32_t countFeatures(XeTeXFont font, uint32_t script, uint32_t language)
{
hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont);
- UInt32 total = 0;
+ uint32_t total = 0;
for (int i = 0; i < 2; ++i) {
uint32_t scriptIndex, langIndex = 0;
@@ -297,7 +297,7 @@ UInt32 countFeatures(XeTeXFont font, UInt32 script, UInt32 language)
return total;
}
-UInt32 getIndFeature(XeTeXFont font, UInt32 script, UInt32 language, UInt32 index)
+uint32_t getIndFeature(XeTeXFont font, uint32_t script, uint32_t language, uint32_t index)
{
hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->hbFont);
@@ -321,7 +321,7 @@ UInt32 getIndFeature(XeTeXFont font, UInt32 script, UInt32 language, UInt32 inde
return 0;
}
-UInt32 countGraphiteFeatures(XeTeXLayoutEngine engine)
+uint32_t countGraphiteFeatures(XeTeXLayoutEngine engine)
{
uint32_t rval = 0;
@@ -334,7 +334,7 @@ UInt32 countGraphiteFeatures(XeTeXLayoutEngine engine)
return rval;
}
-UInt32 getGraphiteFeatureCode(XeTeXLayoutEngine engine, UInt32 index)
+uint32_t getGraphiteFeatureCode(XeTeXLayoutEngine engine, uint32_t index)
{
uint32_t rval = 0;
@@ -349,7 +349,7 @@ UInt32 getGraphiteFeatureCode(XeTeXLayoutEngine engine, UInt32 index)
return rval;
}
-UInt32 countGraphiteFeatureSettings(XeTeXLayoutEngine engine, UInt32 featureID)
+uint32_t countGraphiteFeatureSettings(XeTeXLayoutEngine engine, uint32_t featureID)
{
uint32_t rval = 0;
@@ -364,7 +364,7 @@ UInt32 countGraphiteFeatureSettings(XeTeXLayoutEngine engine, UInt32 featureID)
return rval;
}
-UInt32 getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, UInt32 featureID, UInt32 index)
+uint32_t getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, uint32_t featureID, uint32_t index)
{
uint32_t rval = 0;
@@ -379,10 +379,9 @@ UInt32 getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, UInt32 featureID,
return rval;
}
-void getGraphiteFeatureLabel(XeTeXLayoutEngine engine, UInt32 featureID, char* buf)
+char *
+getGraphiteFeatureLabel(XeTeXLayoutEngine engine, uint32_t featureID)
{
- buf[0] = '\0';
-
hb_face_t* hbFace = hb_font_get_face(engine->font->hbFont);
gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
@@ -391,21 +390,15 @@ void getGraphiteFeatureLabel(XeTeXLayoutEngine engine, UInt32 featureID, char* b
uint32_t len = 0;
uint16_t langID = 0x409;
- buf = (char*) gr_fref_label(feature, &langID, gr_utf8, &len);
-
- if (len > 128 + 1) { // 128 is set in XeTeX_ext.c
- buf = (char*) realloc(buf, len + 1);
- buf = (char*) gr_fref_label(feature, &langID, gr_utf8, &len);
- }
-
- buf[len + 1] = '\0';
+ return (char *) gr_fref_label(feature, &langID, gr_utf8, &len);
}
+
+ return NULL;
}
-void getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, UInt32 featureID, UInt32 settingID, char* buf)
+char *
+getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, uint32_t featureID, uint32_t settingID)
{
- buf[0] = '\0';
-
hb_face_t* hbFace = hb_font_get_face(engine->font->hbFont);
gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
@@ -416,18 +409,12 @@ void getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, UInt32 featureID,
uint32_t len = 0;
uint16_t langID = 0x409;
- buf = (char*) gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
-
- if (len > 128 + 1) { // 128 is set in XeTeX_ext.c
- buf = (char*) realloc(buf, len + 1);
- buf = (char*) gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
- }
-
- buf[len + 1] = '\0';
- break;
+ return (char *) gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
}
}
}
+
+ return NULL;
}
bool
@@ -449,10 +436,13 @@ findGraphiteFeature(XeTeXLayoutEngine engine, const char* s, const char* e, int*
++cp;
while (cp < e && (*cp == ' ' || *cp == '\t'))
++cp;
- if (cp >= e)
+
+ if (cp >= e) {
// no setting was specified, so we just use the first
// XXX the default is not always the first?
+ *v = 1;
return true;
+ }
*v = findGraphiteFeatureSettingNamed(engine, *f, cp, e - cp);
if (*v == -1)
@@ -492,7 +482,7 @@ long findGraphiteFeatureNamed(XeTeXLayoutEngine engine, const char* name, int na
return rval;
}
-long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, UInt32 id, const char* name, int namelength)
+long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, uint32_t id, const char* name, int namelength)
{
long rval = -1;
@@ -523,12 +513,12 @@ long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, UInt32 id, const
return rval;
}
-float getGlyphWidth(XeTeXFont font, UInt32 gid)
+float getGlyphWidth(XeTeXFont font, uint32_t gid)
{
return ((XeTeXFontInst*)font)->getGlyphWidth(gid);
}
-UInt32
+uint32_t
countGlyphs(XeTeXFont font)
{
return ((XeTeXFontInst*)font)->getNumGlyphs();
@@ -555,7 +545,7 @@ float getEmboldenFactor(XeTeXLayoutEngine engine)
}
XeTeXLayoutEngine createLayoutEngine(PlatformFontRef fontRef, XeTeXFont font, char* script, char* language,
- hb_feature_t* features, int nFeatures, char **shapers, UInt32 rgbValue,
+ hb_feature_t* features, int nFeatures, char **shapers, uint32_t rgbValue,
float extend, float slant, float embolden)
{
XeTeXLayoutEngine result = new XeTeXLayoutEngine_rec;
@@ -582,7 +572,7 @@ void deleteLayoutEngine(XeTeXLayoutEngine engine)
delete engine->font;
}
-int layoutChars(XeTeXLayoutEngine engine, UInt16 chars[], SInt32 offset, SInt32 count, SInt32 max,
+int layoutChars(XeTeXLayoutEngine engine, uint16_t chars[], int32_t offset, int32_t count, int32_t max,
bool rightToLeft)
{
bool res;
@@ -657,7 +647,7 @@ int layoutChars(XeTeXLayoutEngine engine, UInt16 chars[], SInt32 offset, SInt32
return glyphCount;
}
-void getGlyphs(XeTeXLayoutEngine engine, UInt32 glyphs[])
+void getGlyphs(XeTeXLayoutEngine engine, uint32_t glyphs[])
{
int glyphCount = hb_buffer_get_length(engine->hbBuffer);
hb_glyph_info_t *hbGlyphs = hb_buffer_get_glyph_infos(engine->hbBuffer, NULL);
@@ -675,6 +665,7 @@ void getGlyphPositions(XeTeXLayoutEngine engine, float positions[])
float x = 0, y = 0;
if (engine->font->getLayoutDirVertical()) {
+ // XXX this does not seem to match the old behaviour
x -= hbPositions[0].y_offset / 64.0; // hack to compensate offset of 1st glyph
for (i = 0; i < glyphCount; i++) {
positions[2*i] = -(x + hbPositions[i].y_offset / 64.0); /* negative is forwards */
@@ -720,12 +711,12 @@ int getDefaultDirection(XeTeXLayoutEngine engine)
return UBIDI_DEFAULT_LTR;
}
-UInt32 getRgbValue(XeTeXLayoutEngine engine)
+uint32_t getRgbValue(XeTeXLayoutEngine engine)
{
return engine->rgbValue;
}
-void getGlyphBounds(XeTeXLayoutEngine engine, UInt32 glyphID, GlyphBBox* bbox)
+void getGlyphBounds(XeTeXLayoutEngine engine, uint32_t glyphID, GlyphBBox* bbox)
{
engine->font->getGlyphBounds(glyphID, bbox);
if (engine->extend != 0.0) {
@@ -734,17 +725,17 @@ void getGlyphBounds(XeTeXLayoutEngine engine, UInt32 glyphID, GlyphBBox* bbox)
}
}
-float getGlyphWidthFromEngine(XeTeXLayoutEngine engine, UInt32 glyphID)
+float getGlyphWidthFromEngine(XeTeXLayoutEngine engine, uint32_t glyphID)
{
return engine->extend * engine->font->getGlyphWidth(glyphID);
}
-void getGlyphHeightDepth(XeTeXLayoutEngine engine, UInt32 glyphID, float* height, float* depth)
+void getGlyphHeightDepth(XeTeXLayoutEngine engine, uint32_t glyphID, float* height, float* depth)
{
engine->font->getGlyphHeightDepth(glyphID, height, depth);
}
-void getGlyphSidebearings(XeTeXLayoutEngine engine, UInt32 glyphID, float* lsb, float* rsb)
+void getGlyphSidebearings(XeTeXLayoutEngine engine, uint32_t glyphID, float* lsb, float* rsb)
{
engine->font->getGlyphSidebearings(glyphID, lsb, rsb);
if (engine->extend != 0.0) {
@@ -753,12 +744,12 @@ void getGlyphSidebearings(XeTeXLayoutEngine engine, UInt32 glyphID, float* lsb,
}
}
-float getGlyphItalCorr(XeTeXLayoutEngine engine, UInt32 glyphID)
+float getGlyphItalCorr(XeTeXLayoutEngine engine, uint32_t glyphID)
{
return engine->extend * engine->font->getGlyphItalCorr(glyphID);
}
-UInt32 mapCharToGlyph(XeTeXLayoutEngine engine, UInt32 charCode)
+uint32_t mapCharToGlyph(XeTeXLayoutEngine engine, uint32_t charCode)
{
return engine->font->mapCharToGlyph(charCode);
}
@@ -768,9 +759,9 @@ UInt32 mapCharToGlyph(XeTeXLayoutEngine engine, UInt32 charCode)
int
findGlyphInPostTable(const char* buffer, int tableSize, const char* glyphName)
{
- const postTable* p = (const postTable*)buffer;
- UInt16 g = 0;
- switch (SWAP(p->format)) {
+ const POSTTable* p = (const POSTTable*)buffer;
+ uint16_t g = 0;
+ switch (SWAP(p->version)) {
case 0x00010000:
{
const char* cp;
@@ -784,11 +775,11 @@ findGlyphInPostTable(const char* buffer, int tableSize, const char* glyphName)
case 0x00020000:
{
- const UInt16* n = (UInt16*)(p + 1);
- UInt16 numGlyphs = SWAP(*n++);
- const UInt8* ps = (const UInt8*)(n + numGlyphs);
+ const uint16_t* n = (uint16_t*)(p + 1);
+ uint16_t numGlyphs = SWAP(*n++);
+ const uint8_t* ps = (const uint8_t*)(n + numGlyphs);
std::vector<std::string> newNames;
- while (ps < (const UInt8*)buffer + tableSize) {
+ while (ps < (const uint8_t*)buffer + tableSize) {
newNames.push_back(std::string((char*)ps + 1, *ps));
ps += *ps + 1;
}
@@ -824,10 +815,10 @@ findGlyphInPostTable(const char* buffer, int tableSize, const char* glyphName)
}
const char*
-getGlyphNamePtr(const char* buffer, int tableSize, UInt16 gid, int* len)
+getGlyphNamePtr(const char* buffer, int tableSize, uint16_t gid, int* len)
{
- const postTable* p = (const postTable*)buffer;
- switch (SWAP(p->format)) {
+ const POSTTable* p = (const POSTTable*)buffer;
+ switch (SWAP(p->version)) {
case 0x00010000:
{
if (gid < 258) {
@@ -839,11 +830,11 @@ getGlyphNamePtr(const char* buffer, int tableSize, UInt16 gid, int* len)
case 0x00020000:
{
- const UInt16* n = (UInt16*)(p + 1);
- UInt16 numGlyphs = SWAP(*n++);
- const UInt8* ps = (const UInt8*)(n + numGlyphs);
- std::vector<const UInt8*> namePtrs;
- while (ps < (const UInt8*)buffer + tableSize) {
+ const uint16_t* n = (uint16_t*)(p + 1);
+ uint16_t numGlyphs = SWAP(*n++);
+ const uint8_t* ps = (const uint8_t*)(n + numGlyphs);
+ std::vector<const uint8_t*> namePtrs;
+ while (ps < (const uint8_t*)buffer + tableSize) {
namePtrs.push_back(ps);
ps += *ps + 1;
}
@@ -891,7 +882,7 @@ getFontCharRange(XeTeXLayoutEngine engine, int reqFirst)
}
const char*
-getGlyphName(XeTeXFont font, UInt16 gid, int* len)
+getGlyphName(XeTeXFont font, uint16_t gid, int* len)
{
return ((XeTeXFontInst*)font)->getGlyphName(gid, *len);
}
@@ -906,7 +897,7 @@ static gr_segment* grSegment = NULL;
static const gr_slot* grPrevSlot = NULL;
bool
-initGraphiteBreaking(XeTeXLayoutEngine engine, const UniChar* txtPtr, int txtLen)
+initGraphiteBreaking(XeTeXLayoutEngine engine, const uint16_t* txtPtr, int txtLen)
{
hb_face_t* hbFace = hb_font_get_face(engine->font->hbFont);
gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h
index 6542345da09..b2a4b0f0fc2 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h
@@ -34,10 +34,6 @@ authorization from the copyright holders.
#ifndef XETEX_LAYOUT_INTERFACE_H
#define XETEX_LAYOUT_INTERFACE_H 1
-#ifdef XETEX_MAC
-#include <Carbon/Carbon.h>
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -64,17 +60,12 @@ extern "C" {
extern char gPrefEngine;
-int getCachedGlyphBBox(UInt16 fontID, UInt16 glyphID, GlyphBBox* bbox);
-void cacheGlyphBBox(UInt16 fontID, UInt16 glyphID, const GlyphBBox* bbox);
+int getCachedGlyphBBox(uint16_t fontID, uint16_t glyphID, GlyphBBox* bbox);
+void cacheGlyphBBox(uint16_t fontID, uint16_t glyphID, const GlyphBBox* bbox);
void terminatefontmanager();
-#ifdef XETEX_MAC
-XeTeXFont createFont(ATSFontRef atsFont, Fixed pointSize);
-#else
-// appropriate functions for other platforms
XeTeXFont createFont(PlatformFontRef fontRef, Fixed pointSize);
-#endif
XeTeXFont createFontFromFile(const char* filename, int index, Fixed pointSize);
void setFontLayoutDir(XeTeXFont font, int vertical);
@@ -92,21 +83,21 @@ double getDesignSize(XeTeXFont font);
void deleteFont(XeTeXFont font);
-void* getFontTablePtr(XeTeXFont font, UInt32 tableTag);
+void* getFontTablePtr(XeTeXFont font, uint32_t tableTag);
Fixed getSlant(XeTeXFont font);
-UInt32 countScripts(XeTeXFont font);
-UInt32 getIndScript(XeTeXFont font, UInt32 index);
-UInt32 countScriptLanguages(XeTeXFont font, UInt32 script);
-UInt32 getIndScriptLanguage(XeTeXFont font, UInt32 script, UInt32 index);
-UInt32 countFeatures(XeTeXFont font, UInt32 script, UInt32 language);
-UInt32 getIndFeature(XeTeXFont font, UInt32 script, UInt32 language, UInt32 index);
-float getGlyphWidth(XeTeXFont font, UInt32 gid);
-UInt32 countGlyphs(XeTeXFont font);
+uint32_t countScripts(XeTeXFont font);
+uint32_t getIndScript(XeTeXFont font, uint32_t index);
+uint32_t countScriptLanguages(XeTeXFont font, uint32_t script);
+uint32_t getIndScriptLanguage(XeTeXFont font, uint32_t script, uint32_t index);
+uint32_t countFeatures(XeTeXFont font, uint32_t script, uint32_t language);
+uint32_t getIndFeature(XeTeXFont font, uint32_t script, uint32_t language, uint32_t index);
+float getGlyphWidth(XeTeXFont font, uint32_t gid);
+uint32_t countGlyphs(XeTeXFont font);
XeTeXLayoutEngine createLayoutEngine(PlatformFontRef fontRef, XeTeXFont font, char* script, char* language,
- hb_feature_t* features, int nFeatures, char **shapers, UInt32 rgbValue,
+ hb_feature_t* features, int nFeatures, char **shapers, uint32_t rgbValue,
float extend, float slant, float embolden);
void deleteLayoutEngine(XeTeXLayoutEngine engine);
@@ -118,10 +109,10 @@ float getExtendFactor(XeTeXLayoutEngine engine);
float getSlantFactor(XeTeXLayoutEngine engine);
float getEmboldenFactor(XeTeXLayoutEngine engine);
-int layoutChars(XeTeXLayoutEngine engine, UInt16* chars, SInt32 offset, SInt32 count, SInt32 max,
+int layoutChars(XeTeXLayoutEngine engine, uint16_t* chars, int32_t offset, int32_t count, int32_t max,
bool rightToLeft);
-void getGlyphs(XeTeXLayoutEngine engine, UInt32* glyphs);
+void getGlyphs(XeTeXLayoutEngine engine, uint32_t* glyphs);
void getGlyphPositions(XeTeXLayoutEngine engine, float* positions);
@@ -131,30 +122,30 @@ void getAscentAndDescent(XeTeXLayoutEngine engine, float* ascent, float* descent
int getDefaultDirection(XeTeXLayoutEngine engine);
-UInt32 getRgbValue(XeTeXLayoutEngine engine);
+uint32_t getRgbValue(XeTeXLayoutEngine engine);
-void getGlyphBounds(XeTeXLayoutEngine engine, UInt32 glyphID, GlyphBBox* bbox);
+void getGlyphBounds(XeTeXLayoutEngine engine, uint32_t glyphID, GlyphBBox* bbox);
-float getGlyphWidthFromEngine(XeTeXLayoutEngine engine, UInt32 glyphID);
+float getGlyphWidthFromEngine(XeTeXLayoutEngine engine, uint32_t glyphID);
-void getGlyphHeightDepth(XeTeXLayoutEngine engine, UInt32 glyphID, float* height, float* depth);
+void getGlyphHeightDepth(XeTeXLayoutEngine engine, uint32_t glyphID, float* height, float* depth);
-void getGlyphSidebearings(XeTeXLayoutEngine engine, UInt32 glyphID, float* lsb, float* rsb);
+void getGlyphSidebearings(XeTeXLayoutEngine engine, uint32_t glyphID, float* lsb, float* rsb);
-float getGlyphItalCorr(XeTeXLayoutEngine engine, UInt32 glyphID);
+float getGlyphItalCorr(XeTeXLayoutEngine engine, uint32_t glyphID);
-UInt32 mapCharToGlyph(XeTeXLayoutEngine engine, UInt32 charCode);
+uint32_t mapCharToGlyph(XeTeXLayoutEngine engine, uint32_t charCode);
int mapGlyphToIndex(XeTeXLayoutEngine engine, const char* glyphName);
int findGlyphInPostTable(const char* p, int tableSize, const char* glyphName);
-const char* getGlyphName(XeTeXFont font, UInt16 gid, int* len);
+const char* getGlyphName(XeTeXFont font, uint16_t gid, int* len);
int getFontCharRange(XeTeXLayoutEngine engine, int reqFirst);
/* graphite interface functions... */
-bool initGraphiteBreaking(XeTeXLayoutEngine engine, const UniChar* txtPtr, int txtLen);
+bool initGraphiteBreaking(XeTeXLayoutEngine engine, const uint16_t* txtPtr, int txtLen);
int findNextGraphiteBreak(void);
bool usingOpenType(XeTeXLayoutEngine engine);
@@ -163,14 +154,14 @@ bool isOpenTypeMathFont(XeTeXLayoutEngine engine);
bool findGraphiteFeature(XeTeXLayoutEngine engine, const char* s, const char* e, int* f, int* v);
-UInt32 countGraphiteFeatures(XeTeXLayoutEngine engine);
-UInt32 getGraphiteFeatureCode(XeTeXLayoutEngine engine, UInt32 index);
-UInt32 countGraphiteFeatureSettings(XeTeXLayoutEngine engine, UInt32 feature);
-UInt32 getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, UInt32 feature, UInt32 index);
-void getGraphiteFeatureLabel(XeTeXLayoutEngine engine, UInt32 feature, char* buf);
-void getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, UInt32 feature, UInt32 setting, char* buf);
+uint32_t countGraphiteFeatures(XeTeXLayoutEngine engine);
+uint32_t getGraphiteFeatureCode(XeTeXLayoutEngine engine, uint32_t index);
+uint32_t countGraphiteFeatureSettings(XeTeXLayoutEngine engine, uint32_t feature);
+uint32_t getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, uint32_t feature, uint32_t index);
+char* getGraphiteFeatureLabel(XeTeXLayoutEngine engine, uint32_t feature);
+char* getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, uint32_t feature, uint32_t setting);
long findGraphiteFeatureNamed(XeTeXLayoutEngine engine, const char* name, int namelength);
-long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, UInt32 feature, const char* name, int namelength);
+long findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, uint32_t feature, const char* name, int namelength);
#ifdef __cplusplus
};
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp b/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp
index e2c2e9e82ca..a2260a9271e 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp
@@ -67,13 +67,13 @@ static int32_t getCoverage(const Coverage* coverage, GlyphID g)
return -1;
}
-static SInt16 getMathConstant(XeTeXFontInst* fontInst, mathConstantIndex whichConstant)
+static int16_t getMathConstant(XeTeXFontInst* fontInst, mathConstantIndex whichConstant)
{
const char* table = (const char*)fontInst->getFontTable(kMATH);
if (table == NULL)
return 0;
- const UInt16* constants = (const UInt16*)(table + SWAP(((const MathTableHeader*)table)->mathConstants));
+ const uint16_t* constants = (const uint16_t*)(table + SWAP(((const MathTableHeader*)table)->mathConstants));
if (whichConstant < firstMathValueRecord) {
/* it's a simple 16-bit value */
@@ -81,7 +81,7 @@ static SInt16 getMathConstant(XeTeXFontInst* fontInst, mathConstantIndex whichCo
}
else if (whichConstant <= lastMathValueRecord) {
const MathValueRecord* valueRecords = (const MathValueRecord*)
- ((char*)constants + firstMathValueRecord * sizeof(UInt16) - firstMathValueRecord * sizeof(MathValueRecord));
+ ((char*)constants + firstMathValueRecord * sizeof(uint16_t) - firstMathValueRecord * sizeof(MathValueRecord));
return SWAP(valueRecords[whichConstant].value);
}
else if (whichConstant <= lastMathConstant) {
diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_ext.c b/Build/source/texk/web2c/xetexdir/XeTeX_ext.c
index 390243a28d6..f20b5db3ba2 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeX_ext.c
+++ b/Build/source/texk/web2c/xetexdir/XeTeX_ext.c
@@ -3,6 +3,7 @@
Copyright (c) 1994-2008 by SIL International
Copyright (c) 2009, 2011 by Jonathan Kew
Copyright (c) 2012, 2013 by Khaled Hosny
+ Copyright (c) 2012, 2013 by Jiang Jiang
SIL Author(s): Jonathan Kew
@@ -56,12 +57,6 @@ authorization from the copyright holders.
#define EXTERN extern
#include "xetexd.h"
-#ifdef XETEX_MAC
-#undef input /* this is defined in texmfmp.h, but we don't need it and it confuses the carbon headers */
-#undef output
-#include <Carbon/Carbon.h>
-#endif
-
#include "XeTeX_ext.h"
#include <teckit/TECkit_Engine.h>
@@ -97,7 +92,7 @@ authorization from the copyright holders.
/* tables/values used in UTF-8 interpretation -
code is based on ConvertUTF.[ch] sample code
published by the Unicode consortium */
-const UInt32
+const uint32_t
offsetsFromUTF8[6] = {
0x00000000UL,
0x00003080UL,
@@ -107,7 +102,7 @@ offsetsFromUTF8[6] = {
0x82082080UL
};
-const UInt8
+const uint8_t
bytesFromUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -119,20 +114,20 @@ bytesFromUTF8[256] = {
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
-const UInt8
+const uint8_t
firstByteMark[7] = {
0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
};
const int halfShift = 10;
-const UInt32 halfBase = 0x0010000UL;
-const UInt32 halfMask = 0x3FFUL;
-const UInt32 kSurrogateHighStart = 0xD800UL;
-const UInt32 kSurrogateHighEnd = 0xDBFFUL;
-const UInt32 kSurrogateLowStart = 0xDC00UL;
-const UInt32 kSurrogateLowEnd = 0xDFFFUL;
-const UInt32 byteMask = 0x000000BFUL;
-const UInt32 byteMark = 0x00000080UL;
+const uint32_t halfBase = 0x0010000UL;
+const uint32_t halfMask = 0x3FFUL;
+const uint32_t kSurrogateHighStart = 0xD800UL;
+const uint32_t kSurrogateHighEnd = 0xDBFFUL;
+const uint32_t kSurrogateLowStart = 0xDC00UL;
+const uint32_t kSurrogateLowEnd = 0xDFFFUL;
+const uint32_t byteMask = 0x000000BFUL;
+const uint32_t byteMark = 0x00000080UL;
/* if the user specifies a paper size or output driver program */
@@ -157,7 +152,7 @@ void initversionstring(char **versions)
"Compiled with Graphite2 version %d.%d.%d; using %d.%d.%d\n"
"Compiled with HarfBuzz version %s; using %s\n"
#ifdef XETEX_MAC
- "Using Mac OS X Carbon, Cocoa & QuickTime frameworks\n"
+ "Using Mac OS X Core Text, Cocoa & ImageIO frameworks\n"
#else
"Compiled with fontconfig version %d.%d.%d; using %d.%d.%d\n"
"Compiled with libpng version %s; using %s\n"
@@ -293,12 +288,12 @@ conversion_error(int errcode)
#endif
static void
-apply_normalization(UInt32* buf, int len, int norm)
+apply_normalization(uint32_t* buf, int len, int norm)
{
static TECkit_Converter normalizers[2] = { NULL, NULL };
TECkit_Status status;
- UInt32 inUsed, outUsed;
+ uint32_t inUsed, outUsed;
TECkit_Converter *normPtr = &normalizers[norm - 1];
if (*normPtr == NULL) {
status = TECkit_CreateConverter(NULL, 0, 1,
@@ -310,7 +305,7 @@ apply_normalization(UInt32* buf, int len, int norm)
}
}
- status = TECkit_ConvertBuffer(*normPtr, (Byte*)buf, len * sizeof(UInt32), &inUsed,
+ status = TECkit_ConvertBuffer(*normPtr, (Byte*)buf, len * sizeof(uint32_t), &inUsed,
(Byte*)&buffer[first], sizeof(*buffer) * (bufsize - first), &outUsed, 1);
if (status != kStatus_NoError)
buffer_overflow();
@@ -327,14 +322,14 @@ int
input_line(UFILE* f)
{
static char* byteBuffer = NULL;
-static UInt32 *utf32Buf = NULL;
+static uint32_t *utf32Buf = NULL;
int i, tmpLen;
int norm = getinputnormalizationstate();
last = first;
if (f->encodingMode == ICUMAPPING) {
- UInt32 bytesRead = 0;
+ uint32_t bytesRead = 0;
UConverter* cnv;
int outLen;
UErrorCode errorCode = 0;
@@ -368,7 +363,7 @@ static UInt32 *utf32Buf = NULL;
case 1: // NFC
case 2: // NFD
if (utf32Buf == NULL)
- utf32Buf = (UInt32*)xmalloc(bufsize * sizeof(*utf32Buf));
+ utf32Buf = (uint32_t*)xmalloc(bufsize * sizeof(*utf32Buf));
tmpLen = ucnv_toAlgorithmic(UCNV_UTF32_NativeEndian, cnv,
(char*)utf32Buf, bufsize * sizeof(*utf32Buf),
byteBuffer, bytesRead, &errorCode);
@@ -466,7 +461,7 @@ static UBreakIterator* brkIter = NULL;
static int brkLocaleStrNum = 0;
void
-linebreakstart(int f, integer localeStrNum, const UniChar* text, integer textLength)
+linebreakstart(int f, integer localeStrNum, const uint16_t* text, integer textLength)
{
UErrorCode status;
char* locale = (char*)gettexstring(localeStrNum);
@@ -593,7 +588,7 @@ printchars(const unsigned short* str, int len)
#define UTF16_NATIVE kForm_UTF16LE
#endif
-void*
+static void*
load_mapping_file(const char* s, const char* e, char byteMapping)
{
char* mapPath;
@@ -608,7 +603,7 @@ load_mapping_file(const char* s, const char* e, char byteMapping)
FILE* mapFile = fopen(mapPath, FOPEN_RBIN_MODE);
free(mapPath);
if (mapFile) {
- UInt32 mappingSize;
+ uint32_t mappingSize;
Byte* mapping;
TECkit_Status status;
fseek(mapFile, 0, SEEK_END);
@@ -679,7 +674,7 @@ applytfmfontmapping(void* cnv, int c)
{
UniChar in = c;
Byte out[2];
- UInt32 inUsed, outUsed;
+ uint32_t inUsed, outUsed;
TECkit_Status status = TECkit_ConvertBuffer((TECkit_Converter)cnv,
(const Byte*)&in, sizeof(in), &inUsed, out, sizeof(out), &outUsed, 1);
if (outUsed < 1)
@@ -758,8 +753,8 @@ read_tag_with_param(const char* cp, int* param)
unsigned int
read_rgb_a(const char** cp)
{
- UInt32 rgbValue = 0;
- UInt32 alpha = 0;
+ uint32_t rgbValue = 0;
+ uint32_t alpha = 0;
int i;
for (i = 0; i < 6; ++i) {
if ((**cp >= '0') && (**cp <= '9'))
@@ -792,7 +787,7 @@ read_rgb_a(const char** cp)
}
int
-readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, UInt32* rgbValue)
+readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, uint32_t* rgbValue)
// returns 1 to go to next_option, -1 for bad_option, 0 to continue
{
const char* sep;
@@ -871,12 +866,14 @@ readFeatureNumber(const char* s, const char* e, int* f, int* v)
while ((*s == ' ') || (*s == '\t'))
++s;
if (*s++ != '=') {
- if (s >= e)
+ if (s >= e) {
// no setting was specified, so we just use the first
// XXX the default is not always the first?
+ *v = 1;
return true;
- else
+ } else {
return false;
+ }
}
if (*s < '0' || *s > '9')
return false;
@@ -925,7 +922,7 @@ loadOTfont(PlatformFontRef fontRef, XeTeXFont font, Fixed scaled_size, const cha
hb_tag_t tag;
- UInt32 rgbValue = 0x000000FF;
+ uint32_t rgbValue = 0x000000FF;
float extend = 1.0;
float slant = 0.0;
@@ -998,12 +995,9 @@ loadOTfont(PlatformFontRef fontRef, XeTeXFont font, Fixed scaled_size, const cha
|| findGraphiteFeature(engine, cp1, cp2, &tag, &value)) {
features = xrealloc(features, (nFeatures + 1) * sizeof(hb_feature_t));
features[nFeatures].tag = tag;
+ features[nFeatures].value = value;
features[nFeatures].start = 0;
features[nFeatures].end = (unsigned int) -1;
- if (value == 0)
- features[nFeatures].value = 1;
- else
- features[nFeatures].value = value;
nFeatures++;
goto next_option;
}
@@ -1243,13 +1237,13 @@ findnativefont(unsigned char* uname, integer scaled_size)
deleteFont(font);
}
}
-
+
#ifdef XETEX_MAC
/* decide whether to use AAT or OpenType rendering with this font */
if (getReqEngine() == 'A')
goto load_aat;
#endif
-
+
font = createFont(fontRef, scaled_size);
if (font != 0) {
#ifdef XETEX_MAC
@@ -1267,6 +1261,7 @@ findnativefont(unsigned char* uname, integer scaled_size)
rval = loadAATfont(fontRef, scaled_size, featString);
}
#endif
+
/* append the style and feature strings, so that \show\fontID will give a full result */
if (varString != NULL && *varString != 0) {
strcat((char*)nameoffile + 1, "/");
@@ -1296,9 +1291,8 @@ releasefontengine(void* engine, int type_flag)
{
#ifdef XETEX_MAC
if (type_flag == AAT_FONT_FLAG) {
- ATSUDisposeStyle((ATSUStyle)engine);
- }
- else
+ CFRelease((CFDictionaryRef)engine);
+ } else
#endif
if (type_flag == OTGR_FONT_FLAG) {
deleteLayoutEngine((XeTeXLayoutEngine)engine);
@@ -1432,20 +1426,21 @@ otfontget3(integer what, void* pEngine, integer param1, integer param2, integer
void
grprintfontname(integer what, void* pEngine, integer param1, integer param2)
{
- char name[128];
- int n = 0;
+ char* name = NULL;
XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
switch (what) {
case XeTeX_feature_name:
- getGraphiteFeatureLabel(engine, param1, &name[0]);
+ name = getGraphiteFeatureLabel(engine, param1);
break;
case XeTeX_selector_name:
- getGraphiteFeatureSettingLabel(engine, param1, param2, &name[0]);
+ name = getGraphiteFeatureSettingLabel(engine, param1, param2);
break;
}
- while (name[n] != '\0')
- ++n;
- printchars((unsigned short*) &name[0], n);
+
+ if (name != NULL) {
+ printcstring(name);
+ gr_label_destroy(name);
+ }
}
integer
@@ -1487,15 +1482,17 @@ grfontgetnamed1(integer what, void* pEngine, integer param)
#ifdef XETEX_MAC
static UInt32
-atsuColorToRGBA32(ATSURGBAlphaColor a)
+cgColorToRGBA32(CGColorRef color)
{
- UInt32 rval = (UInt8)(a.red * 255.0 + 0.5);
+ const CGFloat *components = CGColorGetComponents(color);
+
+ UInt32 rval = (UInt8)(components[0] * 255.0 + 0.5);
rval <<= 8;
- rval += (UInt8)(a.green * 255.0 + 0.5);
+ rval += (UInt8)(components[1] * 255.0 + 0.5);
rval <<= 8;
- rval += (UInt8)(a.blue * 255.0 + 0.5);
+ rval += (UInt8)(components[2] * 255.0 + 0.5);
rval <<= 8;
- rval += (UInt8)(a.alpha * 255.0 + 0.5);
+ rval += (UInt8)(components[3] * 255.0 + 0.5);
return rval;
}
#endif
@@ -1506,13 +1503,13 @@ int
makeXDVGlyphArrayData(void* pNode)
{
unsigned char* cp;
- UInt16* glyphIDs;
+ uint16_t* glyphIDs;
memoryword* p = pNode;
void* glyph_info;
FixedPoint* locations;
int opcode;
Fixed wid;
- UInt16 glyphCount = native_glyph_count(p);
+ uint16_t glyphCount = native_glyph_count(p);
int i = glyphCount * native_glyph_info_size + 8; /* to guarantee enough space in the buffer */
if (i > xdvBufSize) {
@@ -1524,7 +1521,7 @@ makeXDVGlyphArrayData(void* pNode)
glyph_info = native_glyph_info_ptr(p);
locations = (FixedPoint*)glyph_info;
- glyphIDs = (UInt16*)(locations + glyphCount);
+ glyphIDs = (uint16_t*)(locations + glyphCount);
opcode = XDV_GLYPH_STRING;
for (i = 0; i < glyphCount; ++i)
@@ -1561,7 +1558,7 @@ makeXDVGlyphArrayData(void* pNode)
}
for (i = 0; i < glyphCount; ++i) {
- UInt16 g = glyphIDs[i];
+ uint16_t g = glyphIDs[i];
*cp++ = (g >> 8) & 0xff;
*cp++ = g & 0xff;
}
@@ -1572,16 +1569,16 @@ makeXDVGlyphArrayData(void* pNode)
int
makefontdef(integer f)
{
- UInt16 flags = 0;
- UInt32 variationCount = 0;
- UInt32 rgba;
+ uint16_t flags = 0;
+ uint32_t variationCount = 0;
+ uint32_t rgba;
Fixed size;
const char* psName;
const char* famName;
const char* styName;
- UInt8 psLen;
- UInt8 famLen;
- UInt8 styLen;
+ uint8_t psLen;
+ uint8_t famLen;
+ uint8_t styLen;
int fontDefLength;
char* cp;
PlatformFontRef fontRef = 0;
@@ -1590,39 +1587,46 @@ makefontdef(integer f)
float embolden = 0.0;
#ifdef XETEX_MAC
- ATSUStyle style = NULL;
+ CFDictionaryRef attributes = NULL;
+ CFDictionaryRef variation = NULL;
+
if (fontarea[f] == AAT_FONT_FLAG) {
flags = XDV_FLAG_FONTTYPE_ATSUI;
+ attributes = (CFDictionaryRef) fontlayoutengine[f];
+ CTFontRef font = CFDictionaryGetValue(attributes, kCTFontAttributeName);
+ variation = CTFontCopyVariation(font);
+ if (variation) {
+ variationCount = CFDictionaryGetCount(variation);
+ CFRelease(variation);
+ }
- style = (ATSUStyle)fontlayoutengine[f];
- ATSUGetAllFontVariations(style, 0, 0, 0, &variationCount);
-
- ATSUFontID fontID;
- ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
-
- fontRef = FMGetATSFontRefFromFont(fontID);
- getNames(fontRef, &psName, &famName, &styName);
- /* returns ptrs to strings that belong to the font - do not free! */
+ psName = getFileNameFromCTFont(font);
+ if (psName) {
+ famName = "";
+ styName = "";
+ } else {
+ psName = getNameFromCTFont(font, kCTFontPostScriptNameKey);
+ famName = getNameFromCTFont(font, kCTFontFamilyNameKey);
+ styName = getNameFromCTFont(font, kCTFontStyleNameKey);
+ }
- ATSUVerticalCharacterType vert;
- ATSUGetAttribute(style, kATSUVerticalCharacterTag, sizeof(ATSUVerticalCharacterType), &vert, 0);
- if (vert == kATSUStronglyVertical)
+ if (CFDictionaryGetValue(attributes, kCTVerticalFormsAttributeName))
flags |= XDV_FLAG_VERTICAL;
-
- ATSURGBAlphaColor atsuColor;
- ATSUGetAttribute(style, kATSURGBAlphaColorTag, sizeof(ATSURGBAlphaColor), &atsuColor, 0);
- rgba = atsuColorToRGBA32(atsuColor);
- CGAffineTransform t;
- ATSUGetAttribute(style, kATSUFontMatrixTag, sizeof(CGAffineTransform), &t, 0);
+ CGColorRef color = (CGColorRef) CFDictionaryGetValue(attributes, kCTForegroundColorAttributeName);
+ if (color)
+ rgba = cgColorToRGBA32(color);
+
+ CGAffineTransform t = CTFontGetMatrix(font);
extend = t.a;
slant = t.b;
- float tmp = 0.0;
- if (ATSUGetAttribute(style, kXeTeXEmboldenTag, sizeof(float), &tmp, 0) != kATSUNotSetErr)
- embolden = tmp;
+ CFNumberRef emboldenNumber = CFDictionaryGetValue(attributes, kXeTeXEmboldenAttributeName);
+ if (emboldenNumber)
+ CFNumberGetValue(emboldenNumber, kCFNumberFloatType, &embolden);
- ATSUGetAttribute(style, kATSUSizeTag, sizeof(Fixed), &size, 0);
+ CGFloat fSize = CTFontGetSize(font);
+ size = D2Fix(fSize);
}
else
#endif
@@ -1682,16 +1686,6 @@ makefontdef(integer f)
flags |= XDV_FLAG_COLORED;
}
-#ifdef XETEX_MAC
- if (variationCount > 0) {
- fontDefLength +=
- 2 /* number of variations */
- + 4 * variationCount
- + 4 * variationCount; /* axes and values */
- flags |= XDV_FLAG_VARIATIONS;
- }
-#endif
-
if (extend != 1.0) {
fontDefLength += 4;
flags |= XDV_FLAG_EXTEND;
@@ -1716,14 +1710,14 @@ makefontdef(integer f)
*(Fixed*)cp = SWAP32(size);
cp += 4;
- *(UInt16*)cp = SWAP16(flags);
+ *(uint16_t*)cp = SWAP16(flags);
cp += 2;
- *(UInt8*)cp = psLen;
+ *(uint8_t*)cp = psLen;
cp += 1;
- *(UInt8*)cp = famLen;
+ *(uint8_t*)cp = famLen;
cp += 1;
- *(UInt8*)cp = styLen;
+ *(uint8_t*)cp = styLen;
cp += 1;
memcpy(cp, psName, psLen);
cp += psLen;
@@ -1733,45 +1727,23 @@ makefontdef(integer f)
cp += styLen;
if ((fontflags[f] & FONT_FLAGS_COLORED) != 0) {
- *(UInt32*)cp = SWAP32(rgba);
+ *(uint32_t*)cp = SWAP32(rgba);
cp += 4;
}
-#ifdef XETEX_MAC
- if (variationCount > 0) {
- *(UInt16*)cp = SWAP16(variationCount);
- cp += 2;
- if (variationCount > 0) {
- ATSUGetAllFontVariations(style, variationCount,
- (UInt32*)(cp),
- (SInt32*)(cp + 4 * variationCount),
- 0);
- while (variationCount > 0) {
- /* (potentially) swap two 32-bit values per variation setting,
- and advance cp past them all */
- *(UInt32*)(cp) = SWAP32(*(UInt32*)(cp));
- cp += 4;
- *(UInt32*)(cp) = SWAP32(*(UInt32*)(cp));
- cp += 4;
- --variationCount;
- }
- }
- }
-#endif
-
if (flags & XDV_FLAG_EXTEND) {
Fixed f = D2Fix(extend);
- *(UInt32*)(cp) = SWAP32(f);
+ *(uint32_t*)(cp) = SWAP32(f);
cp += 4;
}
if (flags & XDV_FLAG_SLANT) {
Fixed f = D2Fix(slant);
- *(UInt32*)(cp) = SWAP32(f);
+ *(uint32_t*)(cp) = SWAP32(f);
cp += 4;
}
if (flags & XDV_FLAG_EMBOLDEN) {
Fixed f = D2Fix(embolden);
- *(UInt32*)(cp) = SWAP32(f);
+ *(uint32_t*)(cp) = SWAP32(f);
cp += 4;
}
@@ -1779,12 +1751,12 @@ makefontdef(integer f)
}
int
-applymapping(void* pCnv, const UniChar* txtPtr, int txtLen)
+applymapping(void* pCnv, const uint16_t* txtPtr, int txtLen)
{
TECkit_Converter cnv = (TECkit_Converter)pCnv;
- UInt32 inUsed, outUsed;
+ uint32_t inUsed, outUsed;
TECkit_Status status;
- static UInt32 outLength = 0;
+ static uint32_t outLength = 0;
/* allocate outBuffer if not big enough */
if (outLength < txtLen * sizeof(UniChar) + 32) {
@@ -1837,9 +1809,9 @@ getnativecharheightdepth(integer font, integer ch, scaled* height, scaled* depth
#ifdef XETEX_MAC
if (fontarea[font] == AAT_FONT_FLAG) {
- ATSUStyle style = (ATSUStyle)(fontlayoutengine[font]);
- int gid = MapCharToGlyph_AAT(style, ch);
- GetGlyphHeightDepth_AAT(style, gid, &ht, &dp);
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]);
+ int gid = MapCharToGlyph_AAT(attributes, ch);
+ GetGlyphHeightDepth_AAT(attributes, gid, &ht, &dp);
}
else
#endif
@@ -1887,9 +1859,9 @@ getnativecharsidebearings(integer font, integer ch, scaled* lsb, scaled* rsb)
#ifdef XETEX_MAC
if (fontarea[font] == AAT_FONT_FLAG) {
- ATSUStyle style = (ATSUStyle)(fontlayoutengine[font]);
- int gid = MapCharToGlyph_AAT(style, ch);
- GetGlyphSidebearings_AAT(style, gid, &l, &r);
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]);
+ int gid = MapCharToGlyph_AAT(attributes, ch);
+ GetGlyphSidebearings_AAT(attributes, gid, &l, &r);
}
else
#endif
@@ -1915,11 +1887,11 @@ getglyphbounds(integer font, integer edge, integer gid)
#ifdef XETEX_MAC
if (fontarea[font] == AAT_FONT_FLAG) {
- ATSUStyle style = (ATSUStyle)(fontlayoutengine[font]);
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]);
if (edge & 1)
- GetGlyphSidebearings_AAT(style, gid, &a, &b);
+ GetGlyphSidebearings_AAT(attributes, gid, &a, &b);
else
- GetGlyphHeightDepth_AAT(style, gid, &a, &b);
+ GetGlyphHeightDepth_AAT(attributes, gid, &a, &b);
}
else
#endif
@@ -1954,9 +1926,9 @@ getnativecharwd(integer f, integer c)
scaled wd = 0;
#ifdef XETEX_MAC
if (fontarea[f] == AAT_FONT_FLAG) {
- ATSUStyle style = (ATSUStyle)(fontlayoutengine[f]);
- int gid = MapCharToGlyph_AAT(style, c);
- wd = D2Fix(GetGlyphWidth_AAT(style, gid));
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[f]);
+ int gid = MapCharToGlyph_AAT(attributes, c);
+ wd = D2Fix(GetGlyphWidth_AAT(attributes, gid));
}
else
#endif
@@ -1972,12 +1944,12 @@ getnativecharwd(integer f, integer c)
return wd;
}
-UInt16
+uint16_t
get_native_glyph(void* pNode, unsigned index)
{
memoryword* node = (memoryword*)pNode;
FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
- UInt16* glyphIDs = (UInt16*)(locations + native_glyph_count(node));
+ uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node));
if (index >= native_glyph_count(node))
return 0;
else
@@ -1997,13 +1969,13 @@ measure_native_node(void* pNode, int use_glyph_metrics)
{
memoryword* node = (memoryword*)pNode;
int txtLen = native_length(node);
- const UniChar* txtPtr = (UniChar*)(node + native_node_size);
+ uint16_t* txtPtr = (uint16_t*)(node + native_node_size);
unsigned f = native_font(node);
#ifdef XETEX_MAC
if (fontarea[f] == AAT_FONT_FLAG) {
- /* we're using this font in AAT mode, so fontlayoutengine[f] is actually an ATSUStyle */
+ /* we're using this font in AAT mode, so fontlayoutengine[f] is actually a CFDictionaryRef */
DoAtsuiLayout(node, 0);
}
else
@@ -2014,7 +1986,7 @@ measure_native_node(void* pNode, int use_glyph_metrics)
XeTeXLayoutEngine engine = (XeTeXLayoutEngine)(fontlayoutengine[f]);
FixedPoint* locations;
- UInt16* glyphIDs;
+ uint16_t* glyphIDs;
int realGlyphCount = 0;
/* need to find direction runs within the text, and call layoutChars separately for each */
@@ -2023,7 +1995,7 @@ measure_native_node(void* pNode, int use_glyph_metrics)
float x, y;
void* glyph_info = 0;
static float* positions = 0;
- static UInt32* glyphs = 0;
+ static uint32_t* glyphs = 0;
UBiDi* pBiDi = ubidi_open();
@@ -2042,24 +2014,24 @@ measure_native_node(void* pNode, int use_glyph_metrics)
int32_t logicalStart, length;
for (runIndex = 0; runIndex < nRuns; ++runIndex) {
dir = ubidi_getVisualRun(pBiDi, runIndex, &logicalStart, &length);
- realGlyphCount += layoutChars(engine, (UniChar*)txtPtr, logicalStart, length, txtLen, (dir == UBIDI_RTL));
+ realGlyphCount += layoutChars(engine, txtPtr, logicalStart, length, txtLen, (dir == UBIDI_RTL));
}
if (realGlyphCount > 0) {
double x, y;
glyph_info = xmalloc(realGlyphCount * native_glyph_info_size);
locations = (FixedPoint*)glyph_info;
- glyphIDs = (UInt16*)(locations + realGlyphCount);
+ glyphIDs = (uint16_t*)(locations + realGlyphCount);
realGlyphCount = 0;
x = y = 0.0;
for (runIndex = 0; runIndex < nRuns; ++runIndex) {
int nGlyphs;
dir = ubidi_getVisualRun(pBiDi, runIndex, &logicalStart, &length);
- nGlyphs = layoutChars(engine, (UniChar*)txtPtr, logicalStart, length, txtLen,
+ nGlyphs = layoutChars(engine, txtPtr, logicalStart, length, txtLen,
(dir == UBIDI_RTL));
- glyphs = xmalloc(nGlyphs * sizeof(UInt32));
+ glyphs = xmalloc(nGlyphs * sizeof(uint32_t));
positions = xmalloc((nGlyphs * 2 + 2) * sizeof(float));
getGlyphs(engine, glyphs);
@@ -2086,9 +2058,9 @@ measure_native_node(void* pNode, int use_glyph_metrics)
}
else {
int i;
- realGlyphCount = layoutChars(engine, (UniChar*)txtPtr, 0, txtLen, txtLen, (dir == UBIDI_RTL));
+ realGlyphCount = layoutChars(engine, txtPtr, 0, txtLen, txtLen, (dir == UBIDI_RTL));
- glyphs = xmalloc(realGlyphCount * sizeof(UInt32));
+ glyphs = xmalloc(realGlyphCount * sizeof(uint32_t));
positions = xmalloc((realGlyphCount * 2 + 2) * sizeof(float));
getGlyphs(engine, glyphs);
@@ -2097,7 +2069,7 @@ measure_native_node(void* pNode, int use_glyph_metrics)
if (realGlyphCount > 0) {
glyph_info = xmalloc(realGlyphCount * native_glyph_info_size);
locations = (FixedPoint*)glyph_info;
- glyphIDs = (UInt16*)(locations + realGlyphCount);
+ glyphIDs = (uint16_t*)(locations + realGlyphCount);
for (i = 0; i < realGlyphCount; ++i) {
glyphIDs[i] = glyphs[i];
locations[i].x = D2Fix(positions[2*i]);
@@ -2147,7 +2119,7 @@ measure_native_node(void* pNode, int use_glyph_metrics)
else {
/* this iterates over the glyph data whether it comes from ATSUI or ICU layout */
FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
- UInt16* glyphIDs = (UInt16*)(locations + native_glyph_count(node));
+ uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node));
float yMin = 65536.0;
float yMax = -65536.0;
int i;
@@ -2159,7 +2131,7 @@ measure_native_node(void* pNode, int use_glyph_metrics)
if (getCachedGlyphBBox(f, glyphIDs[i], &bbox) == 0) {
#ifdef XETEX_MAC
if (fontarea[f] == AAT_FONT_FLAG)
- GetGlyphBBox_AAT((ATSUStyle)(fontlayoutengine[f]), glyphIDs[i], &bbox);
+ GetGlyphBBox_AAT((CFDictionaryRef)(fontlayoutengine[f]), glyphIDs[i], &bbox);
else
#endif
if (fontarea[f] == OTGR_FONT_FLAG)
@@ -2189,11 +2161,11 @@ get_native_italic_correction(void* pNode)
unsigned n = native_glyph_count(node);
if (n > 0) {
FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
- UInt16* glyphIDs = (UInt16*)(locations + n);
+ uint16_t* glyphIDs = (uint16_t*)(locations + n);
#ifdef XETEX_MAC
if (fontarea[f] == AAT_FONT_FLAG)
- return D2Fix(GetGlyphItalCorr_AAT((ATSUStyle)(fontlayoutengine[f]), glyphIDs[n-1]))
+ return D2Fix(GetGlyphItalCorr_AAT((CFDictionaryRef)(fontlayoutengine[f]), glyphIDs[n-1]))
+ fontletterspace[f];
#endif
if (fontarea[f] == OTGR_FONT_FLAG)
@@ -2209,12 +2181,12 @@ Fixed
get_native_glyph_italic_correction(void* pNode)
{
memoryword* node = pNode;
- UInt16 gid = native_glyph(node);
+ uint16_t gid = native_glyph(node);
unsigned f = native_font(node);
#ifdef XETEX_MAC
if (fontarea[f] == AAT_FONT_FLAG)
- return D2Fix(GetGlyphItalCorr_AAT((ATSUStyle)(fontlayoutengine[f]), gid));
+ return D2Fix(GetGlyphItalCorr_AAT((CFDictionaryRef)(fontlayoutengine[f]), gid));
#endif
if (fontarea[f] == OTGR_FONT_FLAG)
return D2Fix(getGlyphItalCorr((XeTeXLayoutEngine)(fontlayoutengine[f]), gid));
@@ -2226,7 +2198,7 @@ void
measure_native_glyph(void* pNode, int use_glyph_metrics)
{
memoryword* node = pNode;
- UInt16 gid = native_glyph(node);
+ uint16_t gid = native_glyph(node);
unsigned f = native_font(node);
float ht = 0.0;
@@ -2234,15 +2206,10 @@ measure_native_glyph(void* pNode, int use_glyph_metrics)
#ifdef XETEX_MAC
if (fontarea[f] == AAT_FONT_FLAG) {
- ATSUStyle style = (ATSUStyle)(fontlayoutengine[f]);
- ATSGlyphIdealMetrics metrics;
- OSStatus status = ATSUGlyphGetIdealMetrics(style, 1, &gid, 0, &metrics);
- /* returns values in Quartz points, so we need to convert to TeX points */
- if (status == noErr) {
- node_width(node) = D2Fix(metrics.advance.x * 72.27 / 72.0);
- if (use_glyph_metrics)
- GetGlyphHeightDepth_AAT(style, gid, &ht, &dp);
- }
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[f]);
+ node_width(node) = D2Fix(GetGlyphWidth_AAT(attributes, gid));
+ if (use_glyph_metrics)
+ GetGlyphHeightDepth_AAT(attributes, gid, &ht, &dp);
}
else
#endif
@@ -2275,7 +2242,7 @@ mapchartoglyph(integer font, integer ch)
return 0;
#ifdef XETEX_MAC
if (fontarea[font] == AAT_FONT_FLAG)
- return MapCharToGlyph_AAT((ATSUStyle)(fontlayoutengine[font]), ch);
+ return MapCharToGlyph_AAT((CFDictionaryRef)(fontlayoutengine[font]), ch);
else
#endif
if (fontarea[font] == OTGR_FONT_FLAG)
@@ -2292,7 +2259,7 @@ mapglyphtoindex(integer font)
{
#ifdef XETEX_MAC
if (fontarea[font] == AAT_FONT_FLAG)
- return MapGlyphToIndex_AAT((ATSUStyle)(fontlayoutengine[font]), (const char*)nameoffile + 1);
+ return MapGlyphToIndex_AAT((CFDictionaryRef)(fontlayoutengine[font]), (const char*)nameoffile + 1);
else
#endif
if (fontarea[font] == OTGR_FONT_FLAG)
@@ -2308,7 +2275,7 @@ getfontcharrange(integer font, int first)
{
#ifdef XETEX_MAC
if (fontarea[font] == AAT_FONT_FLAG)
- return GetFontCharRange_AAT((ATSUStyle)(fontlayoutengine[font]), first);
+ return GetFontCharRange_AAT((CFDictionaryRef)(fontlayoutengine[font]), first);
else
#endif
if (fontarea[font] == OTGR_FONT_FLAG)
@@ -2333,115 +2300,41 @@ double Fix2D(Fixed f)
/* these are here, not XeTeX_mac.c, because we need stubs on other platforms */
void
-atsugetfontmetrics(ATSUStyle style, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant)
+atsugetfontmetrics(CFDictionaryRef attributes, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant)
{
#ifdef XETEX_MAC
- *ascent = *descent = *xheight = *capheight = *slant = 0;
-
- ATSUFontID fontID;
- OSStatus status = ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
- if (status != noErr)
- return;
-
- ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID);
-
- Fixed size;
- status = ATSUGetAttribute(style, kATSUSizeTag, sizeof(Fixed), &size, 0);
- if (status != noErr)
- return;
- /* size from the ATSUStyle is in Quartz points; convert to TeX points here */
- double floatSize = Fix2D(size) * 72.27 / 72.0;
-
- ATSFontMetrics metrics;
- status = ATSFontGetHorizontalMetrics(fontRef, kATSOptionFlagsDefault, &metrics);
- if (status != noErr)
- return;
-
- *ascent = D2Fix(metrics.ascent * floatSize);
- *descent = D2Fix(metrics.descent * floatSize);
+ CTFontRef font = fontFromAttributes(attributes);
- if (metrics.italicAngle != 0.0) {
- if (fabs(metrics.italicAngle) < 0.090)
- metrics.italicAngle *= 1000.0; /* hack around apparent ATS bug */
- *slant = D2Fix(tan(-metrics.italicAngle * M_PI / 180.0));
- }
- else {
- /* try to get a (possibly synthetic) POST table, as ATSFontGetHorizontalMetrics
- doesn't seem to return this value for OT/CFF fonts */
- ByteCount tableSize;
- if (ATSFontGetTable(fontRef, kPOST, 0, 0, 0, &tableSize) == noErr) {
- struct POSTTable* post = xmalloc(tableSize);
- ATSFontGetTable(fontRef, kPOST, 0, tableSize, post, 0);
- *slant = D2Fix(tan(Fix2D( - SWAP32(post->italicAngle)) * M_PI / 180.0));
- free(post);
- }
- }
-
- CGAffineTransform t;
- ATSUGetAttribute(style, kATSUFontMatrixTag, sizeof(CGAffineTransform), &t, 0);
- if (t.a != 1.0)
- *slant = D2Fix(Fix2D(*slant) * t.a);
- if (t.b != 0.0)
- *slant += D2Fix(t.b);
-
- if (0 && metrics.xHeight != 0.0) {
- /* currently not using this, as the values from ATS don't seem quite what I'd expect */
- *xheight = D2Fix(metrics.xHeight * floatSize);
- *capheight = D2Fix(metrics.capHeight * floatSize);
- }
- else {
- int glyphID = MapCharToGlyph_AAT(style, 'x');
- float ht, dp;
- if (glyphID != 0) {
- GetGlyphHeightDepth_AAT(style, glyphID, &ht, &dp);
- *xheight = D2Fix(ht);
- }
- else
- *xheight = *ascent / 2; /* arbitrary figure if there's no 'x' in the font */
-
- glyphID = MapCharToGlyph_AAT(style, 'X');
- if (glyphID != 0) {
- GetGlyphHeightDepth_AAT(style, glyphID, &ht, &dp);
- *capheight = D2Fix(ht);
- }
- else
- *capheight = *ascent; /* arbitrary figure if there's no 'X' in the font */
- }
+ *ascent = D2Fix(CTFontGetAscent(font));
+ *descent = D2Fix(CTFontGetDescent(font));
+ *xheight = D2Fix(CTFontGetXHeight(font));
+ *capheight = D2Fix(CTFontGetCapHeight(font));
+ *slant = D2Fix(tan(-CTFontGetSlantAngle(font) * M_PI / 180.0));
#endif
}
int
-atsufontget(int what, ATSUStyle style)
+atsufontget(int what, CFDictionaryRef attributes)
{
int rval = -1;
#ifdef XETEX_MAC
- ATSUFontID fontID;
- ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
- ItemCount count;
+ CTFontRef font = fontFromAttributes(attributes);
+ CFArrayRef list;
switch (what) {
case XeTeX_count_glyphs:
- {
- ByteCount tableSize;
- ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID);
- if (ATSFontGetTable(fontRef, kMAXP, 0, 0, 0, &tableSize) == noErr) {
- struct MAXPTable* table = xmalloc(tableSize);
- ATSFontGetTable(fontRef, kMAXP, 0, tableSize, table, 0);
- rval = SWAP16(table->numGlyphs);
- free(table);
- }
- }
+ rval = CTFontGetGlyphCount(font);
break;
case XeTeX_count_variations:
- if (ATSUCountFontVariations(fontID, &count) == noErr)
- rval = count;
- break;
-
case XeTeX_count_features:
- if (ATSUCountFontFeatureTypes(fontID, &count) == noErr)
- rval = count;
+ list = (what == XeTeX_count_variations ? CTFontCopyVariationAxes(font)
+ : CTFontCopyFeatures(font));
+ if (list) {
+ rval = CFArrayGetCount(list);
+ CFRelease(list);
+ }
break;
}
#endif
@@ -2449,59 +2342,88 @@ atsufontget(int what, ATSUStyle style)
}
int
-atsufontget1(int what, ATSUStyle style, int param)
+atsufontget1(int what, CFDictionaryRef attributes, int param)
{
int rval = -1;
#ifdef XETEX_MAC
- ATSUFontID fontID;
- ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
-
- ATSUFontVariationAxis axis;
- ATSUFontVariationValue value;
- ItemCount count;
- Boolean exclusive;
+ CTFontRef font = fontFromAttributes(attributes);
+
switch (what) {
case XeTeX_variation:
- if (ATSUGetIndFontVariation(fontID, param, &axis, 0, 0, 0) == noErr)
- rval = axis;
+ {
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ if (!axes)
+ break;
+ if (CFArrayGetCount(axes) > param) {
+ CFDictionaryRef variation = CFArrayGetValueAtIndex(axes, param);
+ CFNumberRef identifier = CFDictionaryGetValue(variation, kCTFontVariationAxisIdentifierKey);
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
+ }
+ CFRelease(axes);
break;
+ }
case XeTeX_variation_min:
case XeTeX_variation_max:
case XeTeX_variation_default:
- if (ATSUCountFontVariations(fontID, &count) == noErr)
- while (count-- > 0)
- if (ATSUGetIndFontVariation(fontID, count, &axis,
- (what == XeTeX_variation_min) ? &value : 0,
- (what == XeTeX_variation_max) ? &value : 0,
- (what == XeTeX_variation_default) ? &value : 0) == noErr)
- if (axis == param) {
- rval = value;
- break;
- }
+ {
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ if (!axes)
+ break;
+ CFDictionaryRef variation = findDictionaryInArrayWithIdentifier(axes, kCTFontVariationAxisIdentifierKey, param);
+ CFStringRef key = (what == XeTeX_variation_min ? kCTFontVariationAxisMinimumValueKey :
+ (what == XeTeX_variation_max ? kCTFontVariationAxisMaximumValueKey :
+ kCTFontVariationAxisDefaultValueKey));
+ CFNumberRef value = CFDictionaryGetValue(variation, key);
+ if (value)
+ CFNumberGetValue(value, kCFNumberIntType, &rval);
+ CFRelease(axes);
break;
+ }
case XeTeX_feature_code:
- if (ATSUCountFontFeatureTypes(fontID, &count) == noErr) {
- if (param < count) {
- ATSUFontFeatureType* types = xmalloc(count * sizeof(ATSUFontFeatureType));
- if (ATSUGetFontFeatureTypes(fontID, count, types, 0) == noErr)
- rval = types[param];
- free(types);
- }
+ {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (!features)
+ break;
+ if (CFArrayGetCount(features) > param) {
+ CFDictionaryRef feature = CFArrayGetValueAtIndex(features, param);
+ CFNumberRef identifier = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
}
+ CFRelease(features);
break;
+ }
case XeTeX_is_exclusive_feature:
- if (ATSUGetFontFeatureSelectors(fontID, param, 0, 0, 0, 0, &exclusive) == noErr)
- rval = exclusive ? 1 : 0;
+ {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (!features)
+ break;
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param);
+ CFBooleanRef value;
+ Boolean found = CFDictionaryGetValueIfPresent(feature, kCTFontFeatureTypeExclusiveKey, (const void **)&value);
+ if (found)
+ rval = CFBooleanGetValue(value);
+ CFRelease(features);
break;
+ }
case XeTeX_count_selectors:
- if (ATSUCountFontFeatureSelectors(fontID, param, &count) == noErr)
- rval = count;
+ {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (!features)
+ break;
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param);
+ if (feature) {
+ CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
+ if (selectors)
+ rval = CFArrayGetCount(selectors);
+ }
+ CFRelease(features);
break;
+ }
}
#endif
@@ -2509,36 +2431,40 @@ atsufontget1(int what, ATSUStyle style, int param)
}
int
-atsufontget2(int what, ATSUStyle style, int param1, int param2)
+atsufontget2(int what, CFDictionaryRef attributes, int param1, int param2)
{
int rval = -1;
#ifdef XETEX_MAC
- ATSUFontID fontID;
- ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
-
- ItemCount count;
- if (ATSUCountFontFeatureSelectors(fontID, param1, &count) == noErr) {
- ATSUFontFeatureSelector* selectors = xmalloc(count * sizeof(ATSUFontFeatureSelector));
- Boolean* isDefault = xmalloc(count * sizeof(Boolean));
- if (ATSUGetFontFeatureSelectors(fontID, param1, count, selectors, isDefault, 0, 0) == noErr) {
- switch (what) {
- case XeTeX_selector_code:
- if (param2 < count)
- rval = selectors[param2];
- break;
-
- case XeTeX_is_default_selector:
- while (count-- > 0)
- if (selectors[count] == param2) {
- rval = isDefault[count] ? 1 : 0;
- break;
+ CTFontRef font = fontFromAttributes(attributes);
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (features) {
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param1);
+ if (feature) {
+ CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
+ if (selectors) {
+ CFDictionaryRef selector;
+ switch (what) {
+ case XeTeX_selector_code:
+ if (CFArrayGetCount(selectors) > param2) {
+ selector = CFArrayGetValueAtIndex(selectors, param2);
+ CFNumberRef identifier = CFDictionaryGetValue(selector, kCTFontFeatureSelectorIdentifierKey);
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
+ }
+ break;
+ case XeTeX_is_default_selector:
+ selector = findDictionaryInArrayWithIdentifier(selectors, kCTFontFeatureSelectorIdentifierKey, param2);
+ if (selector) {
+ CFBooleanRef isDefault;
+ Boolean found = CFDictionaryGetValueIfPresent(selector, kCTFontFeatureSelectorDefaultKey, (const void **)&isDefault);
+ if (found)
+ rval = CFBooleanGetValue(isDefault);
}
- break;
+ break;
+ }
}
}
- free(isDefault);
- free(selectors);
+ CFRelease(features);
}
#endif
@@ -2546,26 +2472,41 @@ atsufontget2(int what, ATSUStyle style, int param1, int param2)
}
int
-atsufontgetnamed(int what, ATSUStyle style)
+atsufontgetnamed(int what, CFDictionaryRef attributes)
{
int rval = -1;
#ifdef XETEX_MAC
- ATSUFontID fontID;
- ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
-
+ CTFontRef font = fontFromAttributes(attributes);
+
switch (what) {
case XeTeX_find_variation_by_name:
- rval = find_axis_by_name(fontID, (const char*)nameoffile + 1, namelength);
- if (rval == 0)
+ {
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ CFDictionaryRef variation = findDictionaryInArray(axes, kCTFontVariationAxisNameKey,
+ (const char*)nameoffile + 1, namelength);
+ if (variation) {
+ CFNumberRef identifier = CFDictionaryGetValue(variation, kCTFontVariationAxisIdentifierKey);
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
+ } else
rval = -1;
+ CFRelease(axes);
break;
+ }
case XeTeX_find_feature_by_name:
- rval = find_feature_by_name(fontID, (const char*)nameoffile + 1, namelength);
- if (rval == 0x0000FFFF)
+ {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ CFDictionaryRef feature = findDictionaryInArray(features, kCTFontFeatureTypeNameKey,
+ (const char*)nameoffile + 1, namelength);
+ if (feature) {
+ CFNumberRef identifier = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
+ } else
rval = -1;
+ CFRelease(features);
break;
+ }
}
#endif
@@ -2573,20 +2514,22 @@ atsufontgetnamed(int what, ATSUStyle style)
}
int
-atsufontgetnamed1(int what, ATSUStyle style, int param)
+atsufontgetnamed1(int what, CFDictionaryRef attributes, int param)
{
int rval = -1;
#ifdef XETEX_MAC
- ATSUFontID fontID;
- ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
-
- switch (what) {
- case XeTeX_find_selector_by_name:
- rval = find_selector_by_name(fontID, param, (const char*)nameoffile + 1, namelength);
- if (rval == 0x0000FFFF)
- rval = -1;
- break;
+ CTFontRef font = fontFromAttributes(attributes);
+
+ if (what == XeTeX_find_selector_by_name) {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param);
+ if (feature) {
+ CFNumberRef selector = findSelectorByName(feature, (const char*)nameoffile + 1, namelength);
+ if (selector)
+ CFNumberGetValue(selector, kCFNumberIntType, &rval);
+ }
+ CFRelease(features);
}
#endif
@@ -2594,109 +2537,46 @@ atsufontgetnamed1(int what, ATSUStyle style, int param)
}
void
-atsuprintfontname(int what, ATSUStyle style, int param1, int param2)
+atsuprintfontname(int what, CFDictionaryRef attributes, int param1, int param2)
{
#ifdef XETEX_MAC
- ATSUFontID fontID;
- ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
-
- FontNameCode code;
- OSStatus status = -1;
- ItemCount count, i;
- Boolean found = 0;
-
- switch (what) {
- case XeTeX_variation_name:
- status = ATSUCountFontVariations(fontID, &count);
- if (status == noErr) {
- for (i = 0; i < count; ++i) {
- ATSUFontVariationAxis axis;
- ATSUFontVariationValue min, max, def;
- status = ATSUGetIndFontVariation(fontID, i, &axis, &min, &max, &def);
- if (status == noErr && axis == param1) {
- status = ATSUGetFontVariationNameCode(fontID, param1, &code);
- found = 1;
- break;
- }
- }
+ CTFontRef font = fontFromAttributes(attributes);
+ CFStringRef name = NULL;
+ if (what == XeTeX_variation_name) {
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ CFDictionaryRef variation = findDictionaryInArrayWithIdentifier(axes,
+ kCTFontVariationAxisIdentifierKey,
+ param1);
+ if (variation)
+ name = CFDictionaryGetValue(variation, kCTFontVariationAxisNameKey);
+ CFRelease(axes);
+ }
+ else if (what == XeTeX_feature_name || XeTeX_selector_name) {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features,
+ kCTFontFeatureTypeIdentifierKey,
+ param1);
+ if (feature) {
+ if (what == XeTeX_feature_name)
+ name = CFDictionaryGetValue(feature, kCTFontFeatureTypeNameKey);
+ else {
+ CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
+ CFDictionaryRef selector = findDictionaryInArrayWithIdentifier(selectors,
+ kCTFontFeatureSelectorIdentifierKey,
+ param2);
+ if (selector)
+ name = CFDictionaryGetValue(selector, kCTFontFeatureSelectorNameKey);
}
- break;
-
- case XeTeX_feature_name:
- case XeTeX_selector_name:
- status = ATSUCountFontFeatureTypes(fontID, &count);
- if (status == noErr) {
- ATSUFontFeatureType* features = xmalloc(count * sizeof(ATSUFontFeatureType));
- status = ATSUGetFontFeatureTypes(fontID, count, features, &count);
- if (status == noErr) {
- for (i = 0; i < count; ++i) {
- if (features[i] == param1) {
- /* the requested feature code is valid */
- if (what == XeTeX_feature_name) {
- status = ATSUGetFontFeatureNameCode(fontID, param1, kATSUNoSelector, &code);
- found = 1;
- }
- else {
- status = ATSUCountFontFeatureSelectors(fontID, param1, &count);
- if (status == noErr) {
- ATSUFontFeatureSelector* selectors = xmalloc(count * sizeof(ATSUFontFeatureSelector));
- Boolean* onByDefault = xmalloc(count * sizeof(Boolean));
- Boolean exclusive;
- status = ATSUGetFontFeatureSelectors(fontID, param1, count, selectors, onByDefault, &count, &exclusive);
- if (status == noErr) {
- for (i = 0; i < count; ++i) {
- if (selectors[i] == param2) {
- /* feature/selector combination is valid */
- status = ATSUGetFontFeatureNameCode(fontID, param1, param2, &code);
- found = 1;
- break;
- }
- }
- }
- free(onByDefault);
- free(selectors);
- }
- }
- break;
- }
- }
- }
- free(features);
- }
- break;
+ }
+ CFRelease(features);
}
- if (found && status == noErr) {
-#define NAME_BUF_SIZE 1024
- ByteCount len = 0;
- char name[NAME_BUF_SIZE]; /* should be more than enough for any sensible font name */
- do {
- if (ATSUFindFontName(fontID, code, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage, NAME_BUF_SIZE, name, &len, 0) == noErr) break;
- if (ATSUFindFontName(fontID, code, kFontMacintoshPlatform, kFontRomanScript, kFontNoLanguageCode, NAME_BUF_SIZE, name, &len, 0) == noErr) break;
- } while (0);
- if (len > 0) {
- /* need to convert MacRoman name to Unicode */
- CFStringRef str = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8*)name, len, kCFStringEncodingMacRoman, false);
- if (str != NULL) {
- len = CFStringGetLength(str);
- UniChar* buf = xmalloc(len * sizeof(UniChar));
- CFStringGetCharacters(str, CFRangeMake(0, len), buf);
- printchars(buf, len);
- free(buf);
- CFRelease(str);
- }
- }
- else {
- do {
- if (ATSUFindFontName(fontID, code, kFontUnicodePlatform, kFontNoScriptCode, kFontEnglishLanguage, NAME_BUF_SIZE, name, &len, 0) == noErr) break;
- if (ATSUFindFontName(fontID, code, kFontMicrosoftPlatform, kFontNoScriptCode, kFontEnglishLanguage, NAME_BUF_SIZE, name, &len, 0) == noErr) break;
- if (ATSUFindFontName(fontID, code, kFontUnicodePlatform, kFontNoScriptCode, kFontNoLanguageCode, NAME_BUF_SIZE, name, &len, 0) == noErr) break;
- if (ATSUFindFontName(fontID, code, kFontMicrosoftPlatform, kFontNoScriptCode, kFontNoLanguageCode, NAME_BUF_SIZE, name, &len, 0) == noErr) break;
- } while (0);
- if (len > 0) {
- printchars((unsigned short*)(&name[0]), len / 2);
- }
- }
+ if (name) {
+ CFIndex len = CFStringGetLength(name);
+ UniChar* buf = xmalloc(len * sizeof(UniChar));
+ CFStringGetCharacters(name, CFRangeMake(0, len), buf);
+ printchars(buf, len);
+ free(buf);
}
#endif
}
@@ -2708,8 +2588,7 @@ printglyphname(integer font, integer gid)
int len = 0;
#ifdef XETEX_MAC
if (fontarea[font] == AAT_FONT_FLAG) {
- ATSUStyle style = (ATSUStyle)(fontlayoutengine[font]);
- s = GetGlyphName_AAT(style, gid, &len);
+ s = GetGlyphNameFromCTFont(fontFromInteger(font), gid, &len);
}
else
#endif
@@ -2729,7 +2608,7 @@ int
u_open_in(unicodefile* f, integer filefmt, const_string fopen_mode, integer mode, integer encodingData)
{
boolean rval;
- *f = malloc(sizeof(UFILE));
+ *f = xmalloc(sizeof(UFILE));
(*f)->encodingMode = 0;
(*f)->conversionData = 0;
(*f)->savedChar = -1;
@@ -2886,7 +2765,7 @@ get_uni_c(UFILE* f)
case UTF8:
c = rval = getc(f->f);
if (rval != EOF) {
- UInt16 extraBytes = bytesFromUTF8[rval];
+ uint16_t extraBytes = bytesFromUTF8[rval];
switch (extraBytes) { /* note: code falls through cases! */
case 3: c = getc(f->f);
if (c < 0x80 || c >= 0xc0) goto bad_utf8;
@@ -2969,18 +2848,18 @@ void
makeutf16name()
{
unsigned char* s = nameoffile + 1;
- UInt32 rval;
- UInt16* t;
+ uint32_t rval;
+ uint16_t* t;
static int name16len = 0;
if (name16len <= namelength) {
if (nameoffile16 != 0)
free(nameoffile16);
name16len = namelength + 10;
- nameoffile16 = xmalloc(name16len * sizeof(UInt16));
+ nameoffile16 = xmalloc(name16len * sizeof(uint16_t));
}
t = nameoffile16;
while (s <= nameoffile + namelength) {
- UInt16 extraBytes;
+ uint16_t extraBytes;
rval = *(s++);
extraBytes = bytesFromUTF8[rval];
switch (extraBytes) { /* note: code falls through cases! */
@@ -3018,10 +2897,10 @@ integer get_native_word_cp(void* pNode, int side)
{
memoryword* node = (memoryword*)pNode;
FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
- UInt16* glyphIDs = (UInt16*)(locations + native_glyph_count(node));
- UInt16 glyphCount = native_glyph_count(node);
+ uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node));
+ uint16_t glyphCount = native_glyph_count(node);
integer f = native_font(node);
- UInt16 actual_glyph;
+ uint16_t actual_glyph;
if (glyphCount == 0)
return 0;
diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_ext.h b/Build/source/texk/web2c/xetexdir/XeTeX_ext.h
index 828801de5d1..73368232034 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeX_ext.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeX_ext.h
@@ -2,6 +2,8 @@
Part of the XeTeX typesetting system
Copyright (c) 1994-2008 by SIL International
Copyright (c) 2009, 2011 by Jonathan Kew
+ Copyright (c) 2012, 2013 by Jiang Jiang
+ Copyright (c) 2012, 2013 by Khaled Hosny
SIL Author(s): Jonathan Kew
@@ -35,28 +37,13 @@ authorization from the copyright holders.
#include <unicode/utypes.h>
#include <w2c/c-auto.h> /* needed for SIZEOF_LONG and NO_DUMP_SHARE */
-/***** copied from TeX/texk/web2c/config.h -- difficult to include in C++ source files ******/
-#ifndef INTEGER_TYPE
-
-#if SIZEOF_LONG > 4 && !defined (NO_DUMP_SHARE)
-/* If we have 64-bit longs and want to share format files (with 32-bit
- machines), use `int'. */
-#define INTEGER_IS_INT
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <w2c/config.h>
+#ifdef __cplusplus
+}
#endif
-
-#ifdef INTEGER_IS_INT
-#define INTEGER_TYPE int
-#define INTEGER_MAX INT_MAX
-#define INTEGER_MIN INT_MIN
-#else
-#define INTEGER_TYPE long
-#define INTEGER_MAX LONG_MAX
-#define INTEGER_MIN LONG_MIN
-#endif /* not INTEGER_IS_INT */
-
-typedef INTEGER_TYPE integer;
-#endif /* not INTEGER_TYPE */
-/***** end of config.h stuff *****/
#ifndef XETEX_UNICODE_FILE_DEFINED
typedef struct UFILE* unicodefile;
@@ -75,21 +62,10 @@ typedef struct UFILE* unicodefile;
but otherwise we'll need these substitute definitions */
#ifdef XETEX_MAC
-#include <Carbon/Carbon.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <ApplicationServices/ApplicationServices.h>
#else
-#ifndef __TECkit_Common_H__
-typedef unsigned char UInt8;
-typedef unsigned short UInt16;
-typedef unsigned int UInt32;
-typedef UInt16 UniChar;
-#endif
-
-typedef signed char SInt8;
-typedef short SInt16;
-typedef int SInt32;
-
-typedef SInt32 OSStatus;
-typedef SInt32 Fixed;
+typedef int32_t Fixed;
typedef struct {
Fixed x;
Fixed y;
@@ -155,7 +131,7 @@ typedef uint16_t GlyphID;
#define native_font(node) node[native_info_offset].qqqq.b1
#define native_glyph_count(node) node[native_info_offset].qqqq.b3
#define native_glyph_info_ptr(node) node[native_glyph_info_offset].ptr
-#define native_glyph_info_size 10 /* info for each glyph is location (FixedPoint) + glyph ID (UInt16) */
+#define native_glyph_info_size 10 /* info for each glyph is location (FixedPoint) + glyph ID (uint16_t) */
#define native_glyph(p) native_length(p) /* glyph ID field in a glyph_node */
@@ -175,19 +151,6 @@ typedef uint16_t GlyphID;
#define kMAXP HB_TAG('m','a','x','p')
#define kOS_2 HB_TAG('O','S','/','2')
-struct postTable {
- Fixed format;
- Fixed italicAngle;
- SInt16 underlinePosition;
- SInt16 underlineThickness;
- UInt16 isFixedPitch;
- UInt16 reserved;
- UInt32 minMemType42;
- UInt32 maxMemType42;
- UInt32 minMemType1;
- UInt32 maxMemType1;
-};
-
typedef struct
{
float xMin;
@@ -198,19 +161,19 @@ typedef struct
/* For Unicode encoding form interpretation... */
-extern const UInt32 offsetsFromUTF8[6];
-extern const UInt8 bytesFromUTF8[256];
-extern const UInt8 firstByteMark[7];
+extern const uint32_t offsetsFromUTF8[6];
+extern const uint8_t bytesFromUTF8[256];
+extern const uint8_t firstByteMark[7];
extern const int halfShift;
-extern const UInt32 halfBase;
-extern const UInt32 halfMask;
-extern const UInt32 kSurrogateHighStart;
-extern const UInt32 kSurrogateHighEnd;
-extern const UInt32 kSurrogateLowStart;
-extern const UInt32 kSurrogateLowEnd;
-extern const UInt32 byteMask;
-extern const UInt32 byteMark;
+extern const uint32_t halfBase;
+extern const uint32_t halfMask;
+extern const uint32_t kSurrogateHighStart;
+extern const uint32_t kSurrogateHighEnd;
+extern const uint32_t kSurrogateLowStart;
+extern const uint32_t kSurrogateLowEnd;
+extern const uint32_t byteMask;
+extern const uint32_t byteMark;
extern const char *papersize;
extern const char *outputdriver;
@@ -243,6 +206,10 @@ extern FT_Library gFreeTypeLibrary;
#include "XeTeXLayoutInterface.h"
+#ifdef XETEX_MAC
+extern const CFStringRef kXeTeXEmboldenAttributeName;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -250,15 +217,14 @@ extern "C" {
void setinputfileencoding(unicodefile f, integer mode, integer encodingData);
void uclose(unicodefile f);
- void linebreakstart(int f, integer localeStrNum, const UniChar* text, integer textLength);
+ void linebreakstart(int f, integer localeStrNum, const uint16_t* text, integer textLength);
int linebreaknext();
int getencodingmodeandinfo(integer* info);
void printutf8str(const unsigned char* str, int len);
void printchars(const unsigned short* str, int len);
- void* load_mapping_file(const char* s, const char* e, char byteMapping);
void* findnativefont(unsigned char* name, integer scaled_size);
void releasefontengine(void* engine, int type_flag);
- int readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, UInt32* rgbValue);
+ int readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, uint32_t* rgbValue);
/* the metrics params here are really TeX 'scaled' values, but that typedef isn't available every place this is included */
void otgetfontmetrics(void* engine, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant);
@@ -279,7 +245,7 @@ extern "C" {
integer otfontget3(integer what, void* engine, integer param1, integer param2, integer param3);
int makeXDVGlyphArrayData(void* p);
int makefontdef(integer f);
- int applymapping(void* cnv, const UniChar* txtPtr, int txtLen);
+ int applymapping(void* cnv, const uint16_t* txtPtr, int txtLen);
void store_justified_native_glyphs(void* node);
void measure_native_node(void* node, int use_glyph_metrics);
Fixed get_native_italic_correction(void* node);
@@ -289,7 +255,7 @@ extern "C" {
integer mapglyphtoindex(integer font);
integer getfontcharrange(integer font, int first);
void printglyphname(integer font, integer gid);
- UInt16 get_native_glyph(void* pNode, unsigned index);
+ uint16_t get_native_glyph(void* pNode, unsigned index);
void grprintfontname(integer what, void* pEngine, integer param1, integer param2);
integer grfontgetnamed(integer what, void* pEngine);
@@ -298,7 +264,7 @@ extern "C" {
double read_double(const char** s);
unsigned int read_rgb_a(const char** cp);
- const char* getGlyphNamePtr(const char* buffer, int tableSize, UInt16 gid, int* len);
+ const char* getGlyphNamePtr(const char* buffer, int tableSize, uint16_t gid, int* len);
int countpdffilepages();
int find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page);
@@ -317,45 +283,43 @@ extern "C" {
int applytfmfontmapping(void* mapping, int c);
#ifndef XETEX_MAC
-typedef void* ATSUStyle; /* dummy declaration just so the stubs can compile */
+typedef void* CFDictionaryRef; /* dummy declaration just so the stubs can compile */
#endif
- int atsufontget(int what, ATSUStyle style);
- int atsufontget1(int what, ATSUStyle style, int param);
- int atsufontget2(int what, ATSUStyle style, int param1, int param2);
- int atsufontgetnamed(int what, ATSUStyle style);
- int atsufontgetnamed1(int what, ATSUStyle style, int param);
- void atsuprintfontname(int what, ATSUStyle style, int param1, int param2);
+ int atsufontget(int what, CFDictionaryRef attrs);
+ int atsufontget1(int what, CFDictionaryRef attrs, int param);
+ int atsufontget2(int what, CFDictionaryRef attrs, int param1, int param2);
+ int atsufontgetnamed(int what, CFDictionaryRef attrs);
+ int atsufontgetnamed1(int what, CFDictionaryRef attrs, int param);
+ void atsuprintfontname(int what, CFDictionaryRef attrs, int param1, int param2);
/* the metrics params here are really TeX 'scaled' (or MacOS 'Fixed') values, but that typedef isn't available every place this is included */
- void atsugetfontmetrics(ATSUStyle style, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant);
+ void atsugetfontmetrics(CFDictionaryRef attrs, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant);
#ifdef XETEX_MAC
-#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
- #include <ApplicationServices/ApplicationServices.h>
- /* These functions have been removed on 10.7; as a workaround, just do
- * a cast as the ATSFontRef and ATSUFontID should have the same value... */
- #define FMGetFontFromATSFontRef(x) ((ATSUFontID) x)
- #define FMGetATSFontRefFromFont(x) ((ATSFontRef) x)
-#endif
-
/* functions in XeTeX_mac.c */
- void* loadAATfont(ATSFontRef fontRef, integer scaled_size, const char* cp1);
+ void* loadAATfont(CTFontDescriptorRef descriptor, integer scaled_size, const char* cp1);
void DoAtsuiLayout(void* node, int justify);
- void GetGlyphBBox_AAT(ATSUStyle style, UInt16 gid, GlyphBBox* bbox);
- float GetGlyphWidth_AAT(ATSUStyle style, UInt16 gid);
- void GetGlyphHeightDepth_AAT(ATSUStyle style, UInt16 gid, float* ht, float* dp);
- void GetGlyphSidebearings_AAT(ATSUStyle style, UInt16 gid, float* lsb, float* rsb);
- int MapCharToGlyph_AAT(ATSUStyle style, UInt32 ch);
- int MapGlyphToIndex_AAT(ATSUStyle style, const char* glyphName);
- int GetGlyphIDFromCGFont(ATSFontRef atsFontRef, const char* glyphName);
- float GetGlyphItalCorr_AAT(ATSUStyle style, UInt16 gid);
- char* GetGlyphName_AAT(ATSUStyle style, UInt16 gid, int* len);
- char* GetGlyphNameFromCGFont(ATSFontRef atsFontRef, UInt16 gid, int* len);
- int GetFontCharRange_AAT(ATSUStyle style, int reqFirst);
- ATSUFontVariationAxis find_axis_by_name(ATSUFontID fontID, const char* name, int nameLength);
- ATSUFontFeatureType find_feature_by_name(ATSUFontID fontID, const char* name, int nameLength);
- ATSUFontFeatureSelector find_selector_by_name(ATSUFontID fontID, ATSUFontFeatureType featureType, const char* name, int nameLength);
+ void GetGlyphBBox_AAT(CFDictionaryRef fontAttrs, uint16_t gid, GlyphBBox* bbox);
+ double GetGlyphWidth_AAT(CFDictionaryRef fontAttrs, uint16_t gid);
+ void GetGlyphHeightDepth_AAT(CFDictionaryRef fontAttrs, uint16_t gid, float* ht, float* dp);
+ void GetGlyphSidebearings_AAT(CFDictionaryRef fontAttrs, uint16_t gid, float* lsb, float* rsb);
+ double GetGlyphItalCorr_AAT(CFDictionaryRef fontAttrs, uint16_t gid);
+ int MapCharToGlyph_AAT(CFDictionaryRef fontAttrs, uint32_t ch);
+ int MapGlyphToIndex_AAT(CFDictionaryRef attributes, const char* glyphName);
+ char* GetGlyphNameFromCTFont(CTFontRef ctFontRef, uint16_t gid, int* len);
+ int GetGlyphIDFromCTFont(CTFontRef ctFontRef, const char* glyphName);
+ CFDictionaryRef findDictionaryInArray(CFArrayRef array, const void* nameKey, const char* name, int nameLength);
+ CFDictionaryRef findDictionaryInArrayWithIdentifier(CFArrayRef array, const void* identifierKey, int identifier);
+ CFNumberRef findSelectorByName(CFDictionaryRef feature, const char* name, int nameLength);
+ char* getNameFromCTFont(CTFontRef ctFontRef, CFStringRef nameKey);
+ char* getFileNameFromCTFont(CTFontRef ctFontRef);
+ int GetFontCharRange_AAT(CFDictionaryRef fontAttrs, int reqFirst);
+ CTFontRef fontFromAttributes(CFDictionaryRef fontAttrs);
+ CTFontRef fontFromInteger(integer font);
+ void getGlyphBBoxFromCTFont(CTFontRef ctFontRef, uint16_t gid, GlyphBBox* bbox);
+ int mapCharToGlyphFromCTFont(CTFontRef font, uint32_t ch, uint32_t vs);
+ double getGlyphWidthFromCTFont(CTFontRef font, uint16_t gid);
#endif
#ifdef __cplusplus
};
diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_mac.c b/Build/source/texk/web2c/xetexdir/XeTeX_mac.c
index bef5ef3c8ac..4f0f186bdf4 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeX_mac.c
+++ b/Build/source/texk/web2c/xetexdir/XeTeX_mac.c
@@ -2,6 +2,8 @@
Part of the XeTeX typesetting system
Copyright (c) 1994-2008 by SIL International
Copyright (c) 2009 by Jonathan Kew
+ Copyright (c) 2012, 2013 by Jiang Jiang
+ Copyright (c) 2012, 2013 by Khaled Hosny
SIL Author(s): Jonathan Kew
@@ -43,9 +45,7 @@ authorization from the copyright holders.
#define EXTERN extern
#include "xetexd.h"
-#undef input /* this is defined in texmfmp.h, but we don't need it and it confuses the carbon headers */
-#include <Carbon/Carbon.h>
-#include <QuickTime/QuickTime.h>
+#include <ApplicationServices/ApplicationServices.h>
#include <teckit/TECkit_Engine.h>
#include "XeTeX_ext.h"
@@ -53,22 +53,6 @@ authorization from the copyright holders.
#include "XeTeXswap.h"
-static ATSUTextLayout sTextLayout = 0;
-
-static void
-InitializeLayout()
-{
- OSStatus status = ATSUCreateTextLayout(&sTextLayout);
- ATSUFontFallbacks fallbacks;
- status = ATSUCreateFontFallbacks(&fallbacks);
- status = ATSUSetObjFontFallbacks(fallbacks, 0, 0, kATSULastResortOnlyFallback);
- ATSUAttributeTag tag = kATSULineFontFallbacksTag;
- ByteCount valueSize = sizeof(fallbacks);
- ATSUAttributeValuePtr value = &fallbacks;
- status = ATSUSetLayoutControls(sTextLayout, 1, &tag, &valueSize, &value);
- status = ATSUSetTransientFontMatching(sTextLayout, true);
-}
-
static inline double
TeXtoPSPoints(double pts)
{
@@ -82,15 +66,20 @@ PStoTeXPoints(double pts)
}
static inline Fixed
-FixedTeXtoPSPoints(Fixed pts)
+FixedPStoTeXPoints(double pts)
{
- return D2Fix(TeXtoPSPoints(Fix2D(pts)));
+ return D2Fix(PStoTeXPoints(pts));
}
-static inline Fixed
-FixedPStoTeXPoints(Fixed pts)
+CTFontRef fontFromAttributes(CFDictionaryRef attributes)
+{
+ return CFDictionaryGetValue(attributes, kCTFontAttributeName);
+}
+
+CTFontRef fontFromInteger(integer font)
{
- return D2Fix(PStoTeXPoints(Fix2D(pts)));
+ CFDictionaryRef attributes = (CFDictionaryRef) fontlayoutengine[font];
+ return fontFromAttributes(attributes);
}
void
@@ -104,336 +93,168 @@ DoAtsuiLayout(void* p, int justify)
exit(1);
}
- if (sTextLayout == 0)
- InitializeLayout();
-
- OSStatus status = noErr;
-
long txtLen = native_length(node);
const UniChar* txtPtr = (UniChar*)(node + native_node_size);
- status = ATSUSetTextPointerLocation(sTextLayout, txtPtr, 0, txtLen, txtLen);
-
- // we're using this font in AAT mode, so fontlayoutengine[f] is actually an ATSUStyle
- ATSUStyle style = (ATSUStyle)(fontlayoutengine[native_font(node)]);
- status = ATSUSetRunStyle(sTextLayout, style, 0, txtLen);
+ CFDictionaryRef attributes = fontlayoutengine[native_font(node)];
+ CFStringRef string = CFStringCreateWithCharactersNoCopy(NULL, txtPtr, txtLen, kCFAllocatorNull);
+ CFAttributedStringRef attrString = CFAttributedStringCreate(NULL, string, attributes);
+ CFRelease(string);
- ATSUAttributeTag tags[] = { kATSULineWidthTag, kATSULineJustificationFactorTag };
- ItemCount numTags = sizeof(tags) / sizeof(ATSUAttributeTag);
+ CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString(attrString);
+ CTLineRef line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, txtLen));
if (justify) {
- ByteCount valSizes[] = { sizeof(Fixed), sizeof(Fract) };
- Fixed wid = FixedTeXtoPSPoints(node_width(node));
- Fract just = fract1;
- ATSUAttributeValuePtr valPtrs[] = { &wid, &just };
- status = ATSUSetLayoutControls(sTextLayout, numTags, tags, valSizes, valPtrs);
- }
-
- ItemCount count;
- ATSLayoutRecord* layoutRec = NULL;
- status = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(sTextLayout, 0,
- kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void*)&layoutRec, &count);
-
- int i;
- int realGlyphCount = 0;
- int lastRealGlyph = 0;
- for (i = 0; i < count; ++i)
- if (layoutRec[i].glyphID < 0xfffe) {
- lastRealGlyph = i;
- ++realGlyphCount;
+ CGFloat lineWidth = TeXtoPSPoints(Fix2D(node_width(node)));
+ CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, TeXtoPSPoints(Fix2D(fract1)), lineWidth);
+ // TODO(jjgod): how to handle the case when justification failed? for
+ // now we just fallback to use the original line.
+ if (justifiedLine) {
+ CFRelease(line);
+ line = justifiedLine;
}
+ }
- void* glyph_info = xmalloc(realGlyphCount * native_glyph_info_size);
- FixedPoint* locations = (FixedPoint*)glyph_info;
- UInt16* glyphIDs = (UInt16*)(locations + realGlyphCount);
+ CFArrayRef glyphRuns = CTLineGetGlyphRuns(line);
+ CFIndex i, runCount = CFArrayGetCount(glyphRuns);
+ CFIndex totalGlyphCount = CTLineGetGlyphCount(line);
+ UInt16* realGlyphIDs = xmalloc(totalGlyphCount * sizeof(UInt16));
+ void* glyph_info = xmalloc(totalGlyphCount * native_glyph_info_size);
+ FixedPoint* locations = (FixedPoint*)glyph_info;
+ Fixed lsUnit = justify ? 0 : fontletterspace[f];
+ Fixed lsDelta = 0;
- Fixed lsUnit = justify ? 0 : fontletterspace[f];
- Fixed lsDelta = 0;
-
- realGlyphCount = 0;
- for (i = 0; i < count; ++i) {
- if (layoutRec[i].glyphID < 0xfffe) {
- if ((layoutRec[i].flags & kATSGlyphInfoIsAttachment) && (lsDelta != 0))
- lsDelta -= lsUnit;
- glyphIDs[realGlyphCount] = layoutRec[i].glyphID;
- locations[realGlyphCount].y = 0; /* FIXME: won't handle baseline offsets */
- locations[realGlyphCount].x = FixedPStoTeXPoints(layoutRec[i].realPos) + lsDelta;
- lsDelta += lsUnit;
- ++realGlyphCount;
+ int realGlyphCount = 0;
+ CGFloat lastGlyphAdvance = 0;
+ for (i = 0; i < runCount; i++) {
+ CTRunRef run = CFArrayGetValueAtIndex(glyphRuns, i);
+ CFIndex count = CTRunGetGlyphCount(run);
+ // TODO(jjgod): Avoid unnecessary allocation with CTRunGetFoosPtr().
+ CGGlyph* glyphs = (CGGlyph*) xmalloc(count * sizeof(CGGlyph));
+ CGPoint* positions = (CGPoint*) xmalloc(count * sizeof(CGPoint));
+ CGSize* advances = (CGSize*) xmalloc(count * sizeof(CGSize));
+ CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs);
+ CTRunGetPositions(run, CFRangeMake(0, 0), positions);
+ CTRunGetAdvances(run, CFRangeMake(0, 0), advances);
+ CFIndex j;
+ for (j = 0; j < count; j++) {
+ if (glyphs[j] < 0xfffe) {
+ realGlyphIDs[realGlyphCount] = glyphs[j];
+ locations[realGlyphCount].x = FixedPStoTeXPoints(positions[j].x) + lsDelta;
+ lastGlyphAdvance = advances[j].width;
+ locations[realGlyphCount].y = FixedPStoTeXPoints(positions[j].y);
+ lsDelta += lsUnit;
+ realGlyphCount++;
+ }
}
+ free(advances);
+ free(glyphs);
+ free(positions);
}
if (lsDelta != 0)
lsDelta -= lsUnit;
+ UInt16* glyphIDs = (UInt16*)(locations + realGlyphCount);
+ memcpy(glyphIDs, realGlyphIDs, realGlyphCount * sizeof(UInt16));
+ free(realGlyphIDs);
+
native_glyph_count(node) = realGlyphCount;
native_glyph_info_ptr(node) = glyph_info;
-
- if (!justify)
- node_width(node) = FixedPStoTeXPoints(layoutRec[count-1].realPos) + lsDelta;
-
- ATSUDirectReleaseLayoutDataArrayPtr(NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void*)&layoutRec);
-
- if (justify)
- ATSUClearLayoutControls(sTextLayout, numTags, tags);
-}
-
-static OSStatus QuadraticClosePath(void *callBackDataPtr)
-{
- return 0;
-}
-
-static OSStatus QuadraticCurve(const Float32Point *pt1, const Float32Point *controlPt, const Float32Point *pt2, void *callBackDataPtr)
-{
- GlyphBBox* data = (GlyphBBox*)callBackDataPtr;
-
- if (pt1->x < data->xMin)
- data->xMin = pt1->x;
- if (pt1->x > data->xMax)
- data->xMax = pt1->x;
- if (pt1->y < data->yMin)
- data->yMin = pt1->y;
- if (pt1->y > data->yMax)
- data->yMax = pt1->y;
-
- if (pt2->x < data->xMin)
- data->xMin = pt2->x;
- if (pt2->x > data->xMax)
- data->xMax = pt2->x;
- if (pt2->y < data->yMin)
- data->yMin = pt2->y;
- if (pt2->y > data->yMax)
- data->yMax = pt2->y;
-
- if (controlPt->x < data->xMin)
- data->xMin = controlPt->x;
- if (controlPt->x > data->xMax)
- data->xMax = controlPt->x;
- if (controlPt->y < data->yMin)
- data->yMin = controlPt->y;
- if (controlPt->y > data->yMax)
- data->yMax = controlPt->y;
-
- return 0;
-}
-
-static OSStatus QuadraticLine(const Float32Point *pt1, const Float32Point *pt2, void *callBackDataPtr)
-{
- GlyphBBox* data = (GlyphBBox*)callBackDataPtr;
-
- if (pt1->x < data->xMin)
- data->xMin = pt1->x;
- if (pt1->x > data->xMax)
- data->xMax = pt1->x;
- if (pt1->y < data->yMin)
- data->yMin = pt1->y;
- if (pt1->y > data->yMax)
- data->yMax = pt1->y;
-
- if (pt2->x < data->xMin)
- data->xMin = pt2->x;
- if (pt2->x > data->xMax)
- data->xMax = pt2->x;
- if (pt2->y < data->yMin)
- data->yMin = pt2->y;
- if (pt2->y > data->yMax)
- data->yMax = pt2->y;
-
- return 0;
-}
-
-static OSStatus QuadraticNewPath(void *callBackDataPtr)
-{
- return 0;
-}
-
-static OSStatus CubicMoveTo(const Float32Point *pt, void *callBackDataPtr)
-{
- GlyphBBox* data = (GlyphBBox*)callBackDataPtr;
-
- if (pt->x < data->xMin)
- data->xMin = pt->x;
- if (pt->x > data->xMax)
- data->xMax = pt->x;
- if (pt->y < data->yMin)
- data->yMin = pt->y;
- if (pt->y > data->yMax)
- data->yMax = pt->y;
-
- return 0;
-}
-
-static OSStatus CubicLineTo(const Float32Point *pt, void *callBackDataPtr)
-{
- GlyphBBox* data = (GlyphBBox*)callBackDataPtr;
-
- if (pt->x < data->xMin)
- data->xMin = pt->x;
- if (pt->x > data->xMax)
- data->xMax = pt->x;
- if (pt->y < data->yMin)
- data->yMin = pt->y;
- if (pt->y > data->yMax)
- data->yMax = pt->y;
-
- return 0;
-}
-
-static OSStatus CubicCurveTo(const Float32Point *pt1, const Float32Point *pt2, const Float32Point *pt3, void *callBackDataPtr)
-{
- GlyphBBox* data = (GlyphBBox*)callBackDataPtr;
-
- if (pt1->x < data->xMin)
- data->xMin = pt1->x;
- if (pt1->x > data->xMax)
- data->xMax = pt1->x;
- if (pt1->y < data->yMin)
- data->yMin = pt1->y;
- if (pt1->y > data->yMax)
- data->yMax = pt1->y;
-
- if (pt2->x < data->xMin)
- data->xMin = pt2->x;
- if (pt2->x > data->xMax)
- data->xMax = pt2->x;
- if (pt2->y < data->yMin)
- data->yMin = pt2->y;
- if (pt2->y > data->yMax)
- data->yMax = pt2->y;
-
- if (pt3->x < data->xMin)
- data->xMin = pt3->x;
- if (pt3->x > data->xMax)
- data->xMax = pt3->x;
- if (pt3->y < data->yMin)
- data->yMin = pt3->y;
- if (pt3->y > data->yMax)
- data->yMax = pt3->y;
- return 0;
-}
+ if (!justify) {
+ node_width(node) =
+ (realGlyphCount > 0 ? locations[realGlyphCount - 1].x : 0) +
+ FixedPStoTeXPoints(lastGlyphAdvance) +
+ lsDelta;
+ }
-static OSStatus CubicClosePath(void *callBackDataPtr)
-{
- return 0;
+ CFRelease(line);
+ CFRelease(typesetter);
}
-void GetGlyphBBox_AAT(ATSUStyle style, UInt16 gid, GlyphBBox* bbox)
- /* returns glyph bounding box in TeX points */
+void getGlyphBBoxFromCTFont(CTFontRef font, UInt16 gid, GlyphBBox* bbox)
{
- ATSCurveType curveType;
- OSStatus status;
-
bbox->xMin = 65536.0;
bbox->yMin = 65536.0;
bbox->xMax = -65536.0;
bbox->yMax = -65536.0;
- status = ATSUGetNativeCurveType(style, &curveType);
- if (status == noErr) {
- OSStatus cbStatus;
-
- if (curveType == kATSCubicCurveType) {
- static ATSCubicMoveToUPP cubicMoveToProc;
- static ATSCubicLineToUPP cubicLineToProc;
- static ATSCubicCurveToUPP cubicCurveToProc;
- static ATSCubicClosePathUPP cubicClosePathProc;
- if (cubicMoveToProc == NULL) {
- cubicMoveToProc = NewATSCubicMoveToUPP(&CubicMoveTo);
- cubicLineToProc = NewATSCubicLineToUPP(&CubicLineTo);
- cubicCurveToProc = NewATSCubicCurveToUPP(&CubicCurveTo);
- cubicClosePathProc = NewATSCubicClosePathUPP(&CubicClosePath);
- }
- status = ATSUGlyphGetCubicPaths(style, gid,
- cubicMoveToProc, cubicLineToProc, cubicCurveToProc, cubicClosePathProc,
- bbox, &cbStatus);
- }
- else {
- static ATSQuadraticNewPathUPP quadraticNewPathProc;
- static ATSQuadraticLineUPP quadraticLineProc;
- static ATSQuadraticCurveUPP quadraticCurveProc;
- static ATSQuadraticClosePathUPP quadraticClosePathProc;
- if (quadraticNewPathProc == NULL) {
- quadraticNewPathProc = NewATSQuadraticNewPathUPP(&QuadraticNewPath);
- quadraticLineProc = NewATSQuadraticLineUPP(&QuadraticLine);
- quadraticCurveProc = NewATSQuadraticCurveUPP(&QuadraticCurve);
- quadraticClosePathProc = NewATSQuadraticClosePathUPP(&QuadraticClosePath);
- }
- status = ATSUGlyphGetQuadraticPaths(style, gid,
- quadraticNewPathProc, quadraticLineProc, quadraticCurveProc, quadraticClosePathProc,
- bbox, &cbStatus);
- }
- }
+ CGRect rect = CTFontGetBoundingRectsForGlyphs(font,
+ 0, /* Use default orientation for now, handle vertical later */
+ (const CGGlyph *) &gid, NULL, 1);
- if (status != noErr || bbox->xMin == 65536.0)
+ if (CGRectIsNull(rect))
bbox->xMin = bbox->yMin = bbox->xMax = bbox->yMax = 0;
else {
// convert PS to TeX points and flip y-axis
- float tmp = bbox->yMin;
- bbox->yMin = -bbox->yMax * 72.27 / 72.0;
- bbox->yMax = -tmp * 72.27 / 72.0;
- bbox->xMin *= 72.27 / 72.0;
- bbox->xMax *= 72.27 / 72.0;
+ // TODO: do we need to flip for bounding rect returned by Core Text?
+ bbox->yMin = -PStoTeXPoints(rect.origin.y + rect.size.height);
+ bbox->yMax = -PStoTeXPoints(rect.origin.y);
+ bbox->xMin = PStoTeXPoints(rect.origin.x);
+ bbox->xMax = PStoTeXPoints(rect.origin.x + rect.size.width);
}
}
-float GetGlyphWidth_AAT(ATSUStyle style, UInt16 gid)
+void GetGlyphBBox_AAT(CFDictionaryRef attributes, UInt16 gid, GlyphBBox* bbox)
+ /* returns glyph bounding box in TeX points */
+{
+ CTFontRef font = fontFromAttributes(attributes);
+ return getGlyphBBoxFromCTFont(font, gid, bbox);
+}
+
+double getGlyphWidthFromCTFont(CTFontRef font, UInt16 gid)
+{
+ CGSize advances[1] = { CGSizeMake(0, 0) };
+ return PStoTeXPoints(CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1));
+}
+
+double GetGlyphWidth_AAT(CFDictionaryRef attributes, UInt16 gid)
/* returns TeX points */
{
- ATSGlyphIdealMetrics metrics;
- OSStatus status = ATSUGlyphGetIdealMetrics(style, 1, &gid, 0, &metrics);
- if (status == noErr)
- return PStoTeXPoints(metrics.advance.x);
- else
- return 0;
+ CTFontRef font = fontFromAttributes(attributes);
+ return getGlyphWidthFromCTFont(font, gid);
}
-void GetGlyphHeightDepth_AAT(ATSUStyle style, UInt16 gid, float* ht, float* dp)
+void GetGlyphHeightDepth_AAT(CFDictionaryRef attributes, UInt16 gid, float* ht, float* dp)
/* returns TeX points */
{
GlyphBBox bbox;
- GetGlyphBBox_AAT(style, gid, &bbox);
+ GetGlyphBBox_AAT(attributes, gid, &bbox);
*ht = bbox.yMax;
*dp = -bbox.yMin;
}
-void GetGlyphSidebearings_AAT(ATSUStyle style, UInt16 gid, float* lsb, float* rsb)
+void GetGlyphSidebearings_AAT(CFDictionaryRef attributes, UInt16 gid, float* lsb, float* rsb)
/* returns TeX points */
{
- ATSGlyphIdealMetrics metrics;
- OSStatus status = ATSUGlyphGetIdealMetrics(style, 1, &gid, 0, &metrics);
- if (status == noErr) {
- GlyphBBox bbox;
- GetGlyphBBox_AAT(style, gid, &bbox);
- *lsb = bbox.xMin;
- *rsb = PStoTeXPoints(metrics.advance.x) - bbox.xMax;
- }
- else {
- *lsb = *rsb = 0;
- }
+ CTFontRef font = fontFromAttributes(attributes);
+ CGSize advances[1] = { CGSizeMake(0, 0) };
+ double advance = CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1);
+ GlyphBBox bbox;
+ getGlyphBBoxFromCTFont(font, gid, &bbox);
+ *lsb = bbox.xMin;
+ *rsb = PStoTeXPoints(advance) - bbox.xMax;
}
-float GetGlyphItalCorr_AAT(ATSUStyle style, UInt16 gid)
+double GetGlyphItalCorr_AAT(CFDictionaryRef attributes, UInt16 gid)
{
- float rval = 0.0;
- ATSGlyphIdealMetrics metrics;
- OSStatus status = ATSUGlyphGetIdealMetrics(style, 1, &gid, 0, &metrics);
- if (status == noErr) {
- GlyphBBox bbox;
- GetGlyphBBox_AAT(style, gid, &bbox);
- if (bbox.xMax > PStoTeXPoints(metrics.advance.x))
- rval = bbox.xMax - PStoTeXPoints(metrics.advance.x);
- }
- return rval;
+ CTFontRef font = fontFromAttributes(attributes);
+ CGSize advances[1] = { CGSizeMake(0, 0) };
+ double advance = CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1);
+
+ GlyphBBox bbox;
+ getGlyphBBoxFromCTFont(font, gid, &bbox);
+
+ if (bbox.xMax > PStoTeXPoints(advance))
+ return bbox.xMax - PStoTeXPoints(advance);
+ return 0;
}
-int MapCharToGlyph_AAT(ATSUStyle style, UInt32 ch)
+int mapCharToGlyphFromCTFont(CTFontRef font, UInt32 ch, UInt32 vs)
{
- UniChar txt[2];
+ UniChar txt[4];
int len = 1;
-
- if (sTextLayout == 0)
- InitializeLayout();
if (ch > 0xffff) {
ch -= 0x10000;
@@ -444,448 +265,377 @@ int MapCharToGlyph_AAT(ATSUStyle style, UInt32 ch)
else
txt[0] = ch;
- OSStatus status = ATSUSetTextPointerLocation(sTextLayout, &txt[0], 0, len, len);
- if (status != noErr)
- return 0;
- status = ATSUSetRunStyle(sTextLayout, style, 0, len);
- if (status != noErr)
- return 0;
-
- ByteCount bufferSize = sizeof(ATSUGlyphInfoArray);
- ATSUGlyphInfoArray info;
- status = ATSUGetGlyphInfo(sTextLayout, 0, len, &bufferSize, &info);
- if (status == noErr) {
- if (bufferSize > 0 && info.numGlyphs > 0)
- return info.glyphs[0].glyphID;
+ if (vs) {
+ if (vs > 0xffff) {
+ vs -= 0x10000;
+ txt[len] = 0xd800 + vs / 1024;
+ txt[len + 1] = 0xdc00 + vs % 1024;
+ len += 2;
+ } else {
+ txt[len] = vs;
+ len += 1;
+ }
}
+
+ CGGlyph glyphs[2] = { 0 };
+ if (CTFontGetGlyphsForCharacters(font, txt, glyphs, len))
+ return glyphs[0];
+
return 0;
}
-int MapGlyphToIndex_AAT(ATSUStyle style, const char* glyphName)
+int MapCharToGlyph_AAT(CFDictionaryRef attributes, UInt32 ch)
{
- ATSUFontID fontID;
- ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
-
- ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID);
-
- ByteCount length;
- OSStatus status = ATSFontGetTable(fontRef, kPOST, 0, 0, 0, &length);
- if (status != noErr)
- goto ats_failed;
-
- void* table = xmalloc(length);
- status = ATSFontGetTable(fontRef, kPOST, 0, length, table, &length);
- if (status != noErr) {
- free(table);
- goto ats_failed;
- }
-
- int rval = findGlyphInPostTable(table, length, glyphName);
- free(table);
-
- if (rval)
- return rval;
-
-ats_failed:
- return GetGlyphIDFromCGFont(fontRef, glyphName);
+ CTFontRef font = fontFromAttributes(attributes);
+ return mapCharToGlyphFromCTFont(font, ch, 0);
}
-int GetGlyphIDFromCGFont(ATSFontRef atsFontRef, const char* glyphName)
+int MapGlyphToIndex_AAT(CFDictionaryRef attributes, const char* glyphName)
{
-#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- if (&CGFontGetGlyphWithGlyphName == NULL)
- return 0;
-
- int rval = 0;
- CFStringRef psname;
- OSStatus status = ATSFontGetPostScriptName(atsFontRef, 0, &psname);
- if ((status == noErr) && psname) {
- CGFontRef cgfont = CGFontCreateWithFontName(psname);
- CFRelease(psname);
- if (cgfont) {
- CFStringRef glyphname = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
- glyphName,
- kCFStringEncodingUTF8,
- kCFAllocatorNull);
- rval = CGFontGetGlyphWithGlyphName(cgfont, glyphname);
- CFRelease(glyphname);
- CGFontRelease(cgfont);
- }
- }
- return rval;
-#else
- return 0;
-#endif
+ CTFontRef font = fontFromAttributes(attributes);
+ return GetGlyphIDFromCTFont(font, glyphName);
}
-char*
-GetGlyphName_AAT(ATSUStyle style, UInt16 gid, int* len)
+int GetGlyphIDFromCTFont(CTFontRef ctFontRef, const char* glyphName)
{
- static char buffer[256];
- const char* namePtr;
-
- ATSUFontID fontID;
- ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &fontID, 0);
-
- ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID);
-
- ByteCount length;
- OSStatus status = ATSFontGetTable(fontRef, kPOST, 0, 0, 0, &length);
- if (status != noErr)
- goto ats_failed;
-
- void* table = xmalloc(length);
- status = ATSFontGetTable(fontRef, kPOST, 0, length, table, &length);
- if (status != noErr) {
- free(table);
- goto ats_failed;
- }
-
- buffer[0] = 0;
- namePtr = getGlyphNamePtr(table, length, gid, len);
- if (*len > 255)
- *len = 255;
- if (namePtr) {
- memcpy(buffer, namePtr, *len);
- buffer[*len] = 0;
- }
-
- free(table);
-
- if (buffer[0])
- return &buffer[0];
-
-ats_failed:
- return GetGlyphNameFromCGFont(fontRef, gid, len);
+ CFStringRef glyphname = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
+ glyphName,
+ kCFStringEncodingUTF8,
+ kCFAllocatorNull);
+ int rval = CTFontGetGlyphWithName(ctFontRef, glyphname);
+ CFRelease(glyphname);
+ return rval;
}
char*
-GetGlyphNameFromCGFont(ATSFontRef atsFontRef, UInt16 gid, int* len)
+GetGlyphNameFromCTFont(CTFontRef ctFontRef, UInt16 gid, int* len)
{
*len = 0;
static char buffer[256];
buffer[0] = 0;
-#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
if (&CGFontCopyGlyphNameForGlyph == NULL)
return &buffer[0];
- CFStringRef psname;
- OSStatus status = ATSFontGetPostScriptName(atsFontRef, 0, &psname);
- if ((status == noErr) && psname) {
- CGFontRef cgfont = CGFontCreateWithFontName(psname);
- CFRelease(psname);
- if (cgfont && gid < CGFontGetNumberOfGlyphs(cgfont)) {
- CFStringRef glyphname = CGFontCopyGlyphNameForGlyph(cgfont, gid);
- if (glyphname) {
- if (CFStringGetCString(glyphname, buffer, 256, kCFStringEncodingUTF8)) {
- *len = strlen(buffer);
- }
- CFRelease(glyphname);
+ CGFontRef cgfont = CTFontCopyGraphicsFont(ctFontRef, 0);
+ if (cgfont && gid < CGFontGetNumberOfGlyphs(cgfont)) {
+ CFStringRef glyphname = CGFontCopyGlyphNameForGlyph(cgfont, gid);
+ if (glyphname) {
+ if (CFStringGetCString(glyphname, buffer, 256, kCFStringEncodingUTF8)) {
+ *len = strlen(buffer);
}
- CGFontRelease(cgfont);
+ CFRelease(glyphname);
}
+ CGFontRelease(cgfont);
}
-#endif
return &buffer[0];
}
int
-GetFontCharRange_AAT(ATSUStyle style, int reqFirst)
+GetFontCharRange_AAT(CFDictionaryRef attributes, int reqFirst)
{
if (reqFirst) {
int ch = 0;
- while (MapCharToGlyph_AAT(style, ch) == 0 && ch < 0x10ffff)
+ while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch < 0x10ffff)
++ch;
return ch;
}
else {
int ch = 0x10ffff;
- while (MapCharToGlyph_AAT(style, ch) == 0 && ch > 0)
+ while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch > 0)
--ch;
return ch;
}
}
-ATSUFontVariationAxis
-find_axis_by_name(ATSUFontID fontID, const char* name, int nameLength)
+char* getNameFromCTFont(CTFontRef ctFontRef, CFStringRef nameKey)
{
- ATSUFontVariationAxis result = 0;
-
- Str255 inName;
- inName[0] = nameLength;
- int i;
- for (i = 0; i < inName[0]; ++i)
- inName[i + 1] = name[i];
-
- ItemCount varCount;
- ATSUCountFontVariations(fontID, &varCount);
- if (varCount > 0) {
- for (i = 0; i < varCount; ++i) {
- ATSUFontVariationAxis axis;
- ATSUGetIndFontVariation(fontID, i, &axis, 0, 0, 0);
- FontNameCode nameCode;
- ATSUGetFontVariationNameCode(fontID, axis, &nameCode);
- Str255 name;
- ByteCount nameLen;
- ATSUFindFontName(fontID, nameCode, kFontMacintoshPlatform, kFontNoScript, kFontNoLanguage,
- 255, (Ptr)&name[1], &nameLen, 0);
- name[0] = nameLen;
- if (EqualString(inName, name, false, true)) {
- result = axis;
- break;
+ CFStringRef name = CTFontCopyName(ctFontRef, nameKey);
+ CFIndex len = CFStringGetLength(name);
+ len = len * 6 + 1;
+ char *buf = xmalloc(len);
+ if (CFStringGetCString(name, buf, len, kCFStringEncodingUTF8))
+ return buf;
+ free(buf);
+ return 0;
+}
+
+char* getFileNameFromCTFont(CTFontRef ctFontRef)
+{
+ char *ret = NULL;
+
+ CFURLRef url = (CFURLRef) CTFontCopyAttribute(ctFontRef, kCTFontURLAttribute);
+ if (url) {
+ UInt8 pathname[PATH_MAX];
+ if (CFURLGetFileSystemRepresentation(url, true, pathname, PATH_MAX)) {
+ int index = 0;
+
+ /* finding face index by searching for preceding font ids with the same FSRef */
+ /* logic copied from FreeType but without using ATS/FS APIs */
+ ATSFontRef id1 = CTFontGetPlatformFont(ctFontRef, NULL);
+ ATSFontRef id2 = id1 - 1;
+ while (id2 > 0) {
+ FSRef dummy;
+ if (noErr != ATSFontGetFileReference(id2, &dummy)) /* check if id2 is valid, any better way? */
+ break;
+ CTFontRef ctFontRef2 = CTFontCreateWithPlatformFont(id2, 0.0, NULL, NULL);
+ CFURLRef url2 = (CFURLRef) CTFontCopyAttribute(ctFontRef2, kCTFontURLAttribute);
+ if (!url2)
+ break;
+ if (!CFEqual(url, url2))
+ break;
+ id2--;
}
+ index = id1 - (id2 + 1);
+
+ char buf[20];
+ if (index > 0)
+ sprintf(buf, ":%d", index);
+ else
+ buf[0] = '\0';
+
+ ret = xmalloc(strlen((char*) pathname) + 2 + strlen(buf) + 1);
+ sprintf(ret, "[%s%s]", pathname, buf);
}
+ CFRelease(url);
}
-
- return result;
+
+ return ret;
}
-ATSUFontFeatureType
-find_feature_by_name(ATSUFontID fontID, const char* name, int nameLength)
+CFDictionaryRef findDictionaryInArrayWithIdentifier(CFArrayRef array,
+ const void* identifierKey,
+ int identifier)
{
- ATSUFontFeatureType result = 0x0000FFFF;
-
- Str255 inName;
- inName[0] = nameLength;
- int i;
- for (i = 0; i < inName[0]; ++i)
- inName[i + 1] = name[i];
-
- ItemCount typeCount;
- ATSUCountFontFeatureTypes(fontID, &typeCount);
- if (typeCount > 0) {
- ATSUFontFeatureType* types = (ATSUFontFeatureType*)xmalloc(typeCount * sizeof(ATSUFontFeatureType));
- ATSUGetFontFeatureTypes(fontID, typeCount, types, 0);
- for (i = 0; i < typeCount; ++i) {
- FontNameCode nameCode;
- ATSUGetFontFeatureNameCode(fontID, types[i], 0x0000FFFF, &nameCode);
- Str255 name;
- ByteCount nameLen;
- ATSUFindFontName(fontID, nameCode, kFontMacintoshPlatform, kFontNoScript, kFontNoLanguage,
- 255, (Ptr)&name[1], &nameLen, 0);
- name[0] = nameLen;
- if (EqualString(inName, name, false, true)) {
- result = types[i];
+ if (!array)
+ return NULL;
+
+ CFDictionaryRef dict = NULL;
+ int value = -1;
+ CFIndex i;
+ for (i = 0; i < CFArrayGetCount(array); i++) {
+ CFDictionaryRef item = CFArrayGetValueAtIndex(array, i);
+ CFNumberRef itemId = CFDictionaryGetValue(item, identifierKey);
+ if (itemId) {
+ CFNumberGetValue(itemId, kCFNumberIntType, &value);
+ if (value == identifier) {
+ dict = item;
break;
}
}
- free((char*)types);
}
-
- return result;
+ return dict;
}
-ATSUFontFeatureSelector
-find_selector_by_name(ATSUFontID fontID, ATSUFontFeatureType featureType, const char* name, int nameLength)
+CFDictionaryRef findDictionaryInArray(CFArrayRef array, const void* nameKey,
+ const char* name, int nameLength)
{
- ATSUFontFeatureSelector result = 0x0000FFFF;
-
- Str255 inName;
- inName[0] = nameLength;
- int i;
- for (i = 0; i < inName[0]; ++i)
- inName[i + 1] = name[i];
-
- ItemCount selectorCount;
- ATSUCountFontFeatureSelectors(fontID, featureType, &selectorCount);
- if (selectorCount > 0) {
- ATSUFontFeatureSelector* selectors = (ATSUFontFeatureSelector*)xmalloc(selectorCount * sizeof(ATSUFontFeatureSelector));
- ATSUGetFontFeatureSelectors(fontID, featureType, selectorCount, selectors, 0, 0, 0);
- for (i = 0; i < selectorCount; ++i) {
- FontNameCode nameCode;
- ATSUGetFontFeatureNameCode(fontID, featureType, selectors[i], &nameCode);
- Str255 name;
- ByteCount nameLen;
- ATSUFindFontName(fontID, nameCode, kFontMacintoshPlatform, kFontNoScript, kFontNoLanguage,
- 255, (Ptr)&name[1], &nameLen, 0);
- name[0] = nameLen;
- if (EqualString(inName, name, false, true)) {
- result = selectors[i];
- break;
- }
+ if (!array)
+ return NULL;
+
+ CFDictionaryRef dict = NULL;
+ CFStringRef itemName = CFStringCreateWithBytes(NULL, name, nameLength,
+ kCFStringEncodingUTF8, false);
+ CFIndex i;
+ for (i = 0; i < CFArrayGetCount(array); i++) {
+ CFDictionaryRef item = CFArrayGetValueAtIndex(array, i);
+ CFStringRef iName = CFDictionaryGetValue(item, nameKey);
+ if (iName && !CFStringCompare(itemName, iName, kCFCompareCaseInsensitive)) {
+ dict = item;
+ break;
}
- free((char*)selectors);
}
-
- return result;
+ CFRelease(itemName);
+ return dict;
+}
+
+CFNumberRef findSelectorByName(CFDictionaryRef feature, const char* name, int nameLength)
+{
+ CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
+ CFDictionaryRef s = findDictionaryInArray(selectors, kCTFontFeatureSelectorNameKey, name, nameLength);
+ CFNumberRef selector = NULL;
+ if (s)
+ selector = CFDictionaryGetValue(s, kCTFontFeatureSelectorIdentifierKey);
+ return selector;
+}
+
+static CFDictionaryRef createFeatureSettingDictionary(CFNumberRef featureTypeIdentifier,
+ CFNumberRef featureSelectorIdentifier)
+{
+ const void* settingKeys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey };
+ const void* settingValues[] = { featureTypeIdentifier, featureSelectorIdentifier };
+
+ return CFDictionaryCreate(kCFAllocatorDefault, settingKeys, settingValues, 2,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}
+const CFStringRef kXeTeXEmboldenAttributeName = CFSTR("XeTeXEmbolden");
+
void*
-loadAATfont(ATSFontRef fontRef, long scaled_size, const char* cp1)
+loadAATfont(CTFontDescriptorRef descriptor, integer scaled_size, const char* cp1)
{
- ATSUFontID fontID = FMGetFontFromATSFontRef(fontRef);
- ATSUStyle style = 0;
- OSStatus status = ATSUCreateStyle(&style);
- float extend = 1.0;
- float slant = 0.0;
- float embolden = 0.0;
- float letterspace = 0.0;
- int i;
-
- if (status == noErr) {
- UInt32 rgbValue;
- Fixed tracking = 0x80000000;
- Fixed atsuSize = FixedTeXtoPSPoints(scaled_size);
-
- ATSStyleRenderingOptions options = kATSStyleNoHinting;
- Fract hangInhibit = fract1;
- ATSUAttributeTag tags[] = { kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag, kATSUHangingInhibitFactorTag };
- ByteCount sizes[] = { sizeof(ATSUFontID), sizeof(Fixed), sizeof(ATSStyleRenderingOptions), sizeof(Fract) };
- ATSUAttributeValuePtr attrs[] = { &fontID, &atsuSize, &options, &hangInhibit };
- ATSUSetAttributes(style, sizeof(tags) / sizeof(ATSUAttributeTag), tags, sizes, attrs);
-
-#define FEAT_ALLOC_CHUNK 8
-#define VAR_ALLOC_CHUNK 4
-
- if (cp1 != NULL) {
- int allocFeats = FEAT_ALLOC_CHUNK;
- UInt16* featureTypes = (UInt16*)xmalloc(allocFeats * sizeof(UInt16));
- UInt16* selectorValues = (UInt16*)xmalloc(allocFeats * sizeof(UInt16));
- int numFeatures = 0;
-
- int allocVars = VAR_ALLOC_CHUNK;
- UInt32* axes = (UInt32*)xmalloc(allocVars * sizeof(UInt32));
- SInt32* values = (SInt32*)xmalloc(allocVars * sizeof(SInt32));
- int numVariations = 0;
-
- // interpret features & variations following ":"
- while (*cp1) {
- // locate beginning of name=value pair
- if (*cp1 == ':' || *cp1 == ';') // skip over separator
- ++cp1;
- while (*cp1 == ' ' || *cp1 == '\t') // skip leading whitespace
- ++cp1;
- if (*cp1 == 0) // break if end of string
- break;
-
- // scan to end of pair
- const char* cp2 = cp1;
- while (*cp2 && *cp2 != ';' && *cp2 != ':')
- ++cp2;
-
- // look for the '=' separator
- const char* cp3 = cp1;
- while (cp3 < cp2 && *cp3 != '=')
- ++cp3;
- if (cp3 == cp2)
- goto bad_option;
-
- // now cp1 points to option name, cp3 to '=', cp2 to ';' or null
-
- // first try for a feature by this name
- ATSUFontFeatureType featureType;
- featureType = find_feature_by_name(fontID, cp1, cp3 - cp1);
- if (featureType != 0x0000FFFF) {
- // look past the '=' separator for setting names
- int featLen = cp3 - cp1;
- ++cp3;
- while (cp3 < cp2) {
- // skip leading whitespace
- while (*cp3 == ' ' || *cp3 == '\t')
- ++cp3;
-
- // possibly multiple settings...
- int disable = 0;
- if (*cp3 == '!') { // check for negation
- disable = 1;
- ++cp3;
- }
-
- // scan for end of setting name
- const char* cp4 = cp3;
- while (cp4 < cp2 && *cp4 != ',')
- ++cp4;
-
- // now cp3 points to name, cp4 to ',' or ';' or null
- ATSUFontFeatureSelector selectorValue = find_selector_by_name(fontID, featureType, cp3, cp4 - cp3);
- if (selectorValue != 0x0000FFFF) {
- if (numFeatures == allocFeats) {
- allocFeats += FEAT_ALLOC_CHUNK;
- featureTypes = xrealloc(featureTypes, allocFeats * sizeof(UInt16));
- selectorValues = xrealloc(selectorValues, allocFeats * sizeof(UInt16));
- }
- featureTypes[numFeatures] = featureType;
- selectorValues[numFeatures] = selectorValue + disable;
- ++numFeatures;
- }
- else {
- fontfeaturewarning(cp1, featLen, cp3, cp4 - cp3);
- }
-
- // point beyond setting name terminator
- cp3 = cp4 + 1;
+ CGFloat ctSize = TeXtoPSPoints(Fix2D(scaled_size));
+ // create a base font instance for applying further attributes
+ CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, ctSize, NULL);
+
+ if (!font)
+ return NULL;
+
+ CFMutableDictionaryRef stringAttributes =
+ CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFMutableDictionaryRef attributes =
+ CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ double tracking = 0.0;
+ float extend = 1.0;
+ float slant = 0.0;
+ float embolden = 0.0;
+ float letterspace = 0.0;
+ UInt32 rgbValue;
+ if (cp1) {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ CFMutableArrayRef featureSettings =
+ CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ CFMutableDictionaryRef variation =
+ CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ // interpret features & variations following ":"
+ while (*cp1) {
+ // locate beginning of name=value pair
+ if (*cp1 == ':' || *cp1 == ';') // skip over separator
+ ++cp1;
+ while (*cp1 == ' ' || *cp1 == '\t') // skip leading whitespace
+ ++cp1;
+ if (*cp1 == 0) // break if end of string
+ break;
+
+ // scan to end of pair
+ const char* cp2 = cp1;
+ while (*cp2 && *cp2 != ';' && *cp2 != ':')
+ ++cp2;
+
+ // look for the '=' separator
+ const char* cp3 = cp1;
+ while (cp3 < cp2 && *cp3 != '=')
+ ++cp3;
+ if (cp3 == cp2)
+ goto bad_option;
+
+ // now cp1 points to option name, cp3 to '=', cp2 to ';' or null
+
+ // first try for a feature by this name
+ CFDictionaryRef feature = findDictionaryInArray(features, kCTFontFeatureTypeNameKey, cp1, cp3 - cp1);
+ if (feature) {
+ // look past the '=' separator for setting names
+ int featLen = cp3 - cp1;
+ ++cp3;
+ int zeroInteger = 0;
+ CFNumberRef zero = CFNumberCreate(NULL, kCFNumberIntType, &zeroInteger);
+ while (cp3 < cp2) {
+ // skip leading whitespace
+ while (*cp3 == ' ' || *cp3 == '\t')
+ ++cp3;
+
+ // possibly multiple settings...
+ int disable = 0;
+ if (*cp3 == '!') { // check for negation
+ disable = 1;
+ ++cp3;
}
-
- goto next_option;
+
+ // scan for end of setting name
+ const char* cp4 = cp3;
+ while (cp4 < cp2 && *cp4 != ',')
+ ++cp4;
+
+ // now cp3 points to name, cp4 to ',' or ';' or null
+ CFNumberRef selector = findSelectorByName(feature, cp3, cp4 - cp3);
+ if (selector && CFNumberCompare(selector, zero, NULL) >= 0) {
+ CFNumberRef featureType = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
+ CFDictionaryRef featureSetting = createFeatureSettingDictionary(featureType, selector);
+ CFArrayAppendValue(featureSettings, featureSetting);
+ CFRelease(featureSetting);
+ } else {
+ fontfeaturewarning(cp1, featLen, cp3, cp4 - cp3);
+ }
+
+ // point beyond setting name terminator
+ cp3 = cp4 + 1;
}
-
- // try to find a variation by this name
- ATSUFontVariationAxis axis;
- axis = find_axis_by_name(fontID, cp1, cp3 - cp1);
- if (axis != 0) {
- // look past the '=' separator for the value
+ CFRelease(zero);
+
+ goto next_option;
+ }
+
+ // try to find a variation by this name
+ CFDictionaryRef axis = findDictionaryInArray(axes, kCTFontVariationAxisNameKey, cp1, cp3 - cp1);
+ if (axis) {
+ // look past the '=' separator for the value
+ ++cp3;
+ double value = 0.0, decimal = 1.0;
+ bool negate = false;
+ if (*cp3 == '-') {
++cp3;
- double value = 0.0, decimal = 1.0;
- bool negate = false;
- if (*cp3 == '-') {
- ++cp3;
- negate = true;
- }
- while (cp3 < cp2) {
- int v = *cp3 - '0';
- if (v >= 0 && v <= 9) {
- if (decimal != 1.0) {
- value += v / decimal;
- decimal *= 10.0;
- }
- else
- value = value * 10.0 + v;
- }
- else if (*cp3 == '.') {
- if (decimal != 1.0)
- break;
- decimal = 10.0;
+ negate = true;
+ }
+ while (cp3 < cp2) {
+ int v = *cp3 - '0';
+ if (v >= 0 && v <= 9) {
+ if (decimal != 1.0) {
+ value += v / decimal;
+ decimal *= 10.0;
}
else
- break;
- ++cp3;
+ value = value * 10.0 + v;
}
- if (negate)
- value = -value;
- if (numVariations == allocVars) {
- allocVars += VAR_ALLOC_CHUNK;
- axes = xrealloc(axes, allocVars * sizeof(UInt32));
- values = xrealloc(values, allocVars * sizeof(SInt32));
+ else if (*cp3 == '.') {
+ if (decimal != 1.0)
+ break;
+ decimal = 10.0;
}
- axes[numVariations] = axis;
- values[numVariations] = value * 65536.0; // D2Fix(value);
- ++numVariations;
-
- goto next_option;
- }
-
- // didn't find feature or variation, try other options....
-
- i = readCommonFeatures(cp1, cp2, &extend, &slant, &embolden, &letterspace, &rgbValue);
- if (i == 1)
- goto next_option;
- else if (i == -1)
- goto bad_option;
-
- if (strncmp(cp1, "tracking", 8) == 0) {
- cp3 = cp1 + 8;
- if (*cp3 != '=')
- goto bad_option;
+ else
+ break;
++cp3;
- double val = read_double(&cp3);
- tracking = D2Fix(val);
- goto next_option;
}
-
+ if (negate)
+ value = -value;
+
+ CFNumberRef axisIdentifier = CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey);
+ CFNumberRef axisValue = CFNumberCreate(NULL, kCFNumberDoubleType, &value);
+ CFDictionaryAddValue(variation, axisIdentifier, axisValue);
+ CFRelease(axisValue);
+
+ goto next_option;
+ }
+
+ // didn't find feature or variation, try other options...
+ int ret = readCommonFeatures(cp1, cp2, &extend, &slant, &embolden, &letterspace, &rgbValue);
+ if (ret == 1)
+ goto next_option;
+ else if (ret == -1)
+ goto bad_option;
+
+ if (strncmp(cp1, "tracking", 8) == 0) {
+ cp3 = cp1 + 8;
+ if (*cp3 != '=')
+ goto bad_option;
+ ++cp3;
+ tracking = read_double(&cp3);
+ CFNumberRef trackingNumber = CFNumberCreate(NULL, kCFNumberDoubleType, &tracking);
+ CFDictionaryAddValue(stringAttributes, kCTKernAttributeName, trackingNumber);
+ CFRelease(trackingNumber);
+ goto next_option;
+ }
+
bad_option:
- // not a name=value pair, or not recognized....
+ // not a name=value pair, or not recognized....
// check for plain "vertical" before complaining
if (strncmp(cp1, "vertical", 8) == 0) {
cp3 = cp2;
@@ -896,75 +646,69 @@ loadAATfont(ATSFontRef fontRef, long scaled_size, const char* cp1)
if (*cp3)
++cp3;
if (cp3 == cp1 + 8) {
- ATSUVerticalCharacterType vert = kATSUStronglyVertical;
- tags[0] = kATSUVerticalCharacterTag;
- sizes[0] = sizeof(ATSUVerticalCharacterType);
- attrs[0] = &vert;
- ATSUSetAttributes(style, 1, tags, sizes, attrs);
+ int orientation = kCTFontVerticalOrientation;
+ CFNumberRef orientationNumber = CFNumberCreate(NULL, kCFNumberIntType, &orientation);
+ CFDictionaryAddValue(attributes, kCTFontOrientationAttribute, orientationNumber);
+ CFRelease(orientationNumber);
+ CFDictionaryAddValue(stringAttributes, kCTVerticalFormsAttributeName, kCFBooleanTrue);
goto next_option;
}
}
-
+
fontfeaturewarning(cp1, cp2 - cp1, 0, 0);
-
+
next_option:
// go to next name=value pair
cp1 = cp2;
- }
-
- if (numFeatures > 0)
- ATSUSetFontFeatures(style, numFeatures, featureTypes, selectorValues);
-
- if (numVariations > 0)
- ATSUSetVariations(style, numVariations, axes, values);
-
- if ((loadedfontflags & FONT_FLAGS_COLORED) != 0) {
- ATSURGBAlphaColor rgba;
- rgba.red = ((rgbValue & 0xFF000000) >> 24) / 255.0;
- rgba.green = ((rgbValue & 0x00FF0000) >> 16) / 255.0;
- rgba.blue = ((rgbValue & 0x0000FF00) >> 8 ) / 255.0;
- rgba.alpha = ((rgbValue & 0x000000FF) ) / 255.0;
- tags[0] = kATSURGBAlphaColorTag;
- sizes[0] = sizeof(ATSURGBAlphaColor);
- attrs[0] = &rgba;
- ATSUSetAttributes(style, 1, tags, sizes, attrs);
- }
-
- if (tracking != 0x80000000) {
- tags[0] = kATSUTrackingTag;
- sizes[0] = sizeof(Fixed);
- attrs[0] = &tracking;
- ATSUSetAttributes(style, 1, tags, sizes, attrs);
- }
-
- if (extend != 1.0 || slant != 0.0) {
- CGAffineTransform t = { extend, slant, 0, 1.0, 0, 0 };
- tags[0] = kATSUFontMatrixTag;
- sizes[0] = sizeof(CGAffineTransform);
- attrs[0] = &t;
- ATSUSetAttributes(style, 1, tags, sizes, attrs);
- }
-
- if (embolden != 0.0) {
- embolden = embolden * Fix2D(scaled_size) / 100.0;
- tags[0] = kXeTeXEmboldenTag;
- sizes[0] = sizeof(float);
- attrs[0] = &embolden;
- ATSUSetAttributes(style, 1, tags, sizes, attrs);
- }
-
- if (letterspace != 0.0)
- loadedfontletterspace = (letterspace / 100.0) * scaled_size;
-
- free((char*)featureTypes);
- free((char*)selectorValues);
- free((char*)axes);
- free((char*)values);
}
+
+ if (features)
+ CFRelease(features);
+ if (axes)
+ CFRelease(axes);
+
+ if (CFArrayGetCount(featureSettings))
+ CFDictionaryAddValue(attributes, kCTFontFeatureSettingsAttribute, featureSettings);
+ CFRelease(featureSettings);
+
+ if (CFDictionaryGetCount(variation))
+ CFDictionaryAddValue(attributes, kCTFontVariationAttribute, variation);
+ CFRelease(variation);
+ }
+
+ if ((loadedfontflags & FONT_FLAGS_COLORED) != 0) {
+ CGFloat red = ((rgbValue & 0xFF000000) >> 24) / 255.0;
+ CGFloat green = ((rgbValue & 0x00FF0000) >> 16) / 255.0;
+ CGFloat blue = ((rgbValue & 0x0000FF00) >> 8 ) / 255.0;
+ CGFloat alpha = ((rgbValue & 0x000000FF) ) / 255.0;
+ CGColorRef color = CGColorCreateGenericRGB(red, green, blue, alpha);
+ CFDictionaryAddValue(stringAttributes, kCTForegroundColorAttributeName, color);
+ CGColorRelease(color);
+ }
+
+ CGAffineTransform matrix = CGAffineTransformIdentity;
+ if (extend != 1.0 || slant != 0.0)
+ matrix = CGAffineTransformMake(extend, slant, 0, 1.0, 0, 0);
+
+ if (embolden != 0.0) {
+ embolden = embolden * Fix2D(scaled_size) / 100.0;
+ CFNumberRef emboldenNumber = CFNumberCreate(NULL, kCFNumberFloatType, &embolden);
+ CFDictionaryAddValue(stringAttributes, kXeTeXEmboldenAttributeName, emboldenNumber);
+ CFRelease(emboldenNumber);
}
+ if (letterspace != 0.0)
+ loadedfontletterspace = (letterspace / 100.0) * scaled_size;
+
+ descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+ CFRelease(attributes);
+ CTFontRef actualFont = CTFontCreateCopyWithAttributes(font, ctSize, &matrix, descriptor);
+ CFRelease(font);
+ CFDictionaryAddValue(stringAttributes, kCTFontAttributeName, actualFont);
+ CFRelease(actualFont);
+
nativefonttypeflag = AAT_FONT_FLAG;
- return style;
+ return (void *) stringAttributes;
}
int
@@ -1005,10 +749,6 @@ find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page)
picFileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8*)pic_path, strlen(pic_path), false);
if (picFileURL != NULL) {
- /* get an FSRef for the URL we constructed */
- FSRef picFileRef;
- CFURLGetFSRef(picFileURL, &picFileRef);
-
if (pdfBoxType > 0) {
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(picFileURL);
if (document != NULL) {
@@ -1077,22 +817,26 @@ find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page)
}
}
else {
- /* make an FSSpec for the file, and try to import it as a pic */
- FSSpec picFileSpec;
- result = FSGetCatalogInfo(&picFileRef, kFSCatInfoNone, NULL, NULL, &picFileSpec, NULL);
- if (result == noErr) {
- ComponentInstance ci;
- result = GetGraphicsImporterForFile(&picFileSpec, &ci);
- if (result == noErr) {
- ImageDescriptionHandle desc = NULL;
- result = GraphicsImportGetImageDescription(ci, &desc);
- bounds->x = 0;
- bounds->y = 0;
- bounds->wd = (*desc)->width * 72.27 / Fix2D((*desc)->hRes);
- bounds->ht = (*desc)->height * 72.27 / Fix2D((*desc)->vRes);
- DisposeHandle((Handle)desc);
- (void)CloseComponent(ci);
- }
+ CGImageSourceRef picFileSource = CGImageSourceCreateWithURL(picFileURL, NULL);
+ if (picFileSource) {
+ CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(picFileSource, 0, NULL);
+
+ CFNumberRef imageWidth = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);
+ CFNumberRef imageHeight = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);
+ CFNumberRef DPIWidth = CFDictionaryGetValue(properties, kCGImagePropertyDPIWidth);
+ CFNumberRef DPIHeight = CFDictionaryGetValue(properties, kCGImagePropertyDPIHeight);
+ int w = 0, h = 0, hRes = 72, vRes = 72;
+ CFNumberGetValue(imageWidth, kCFNumberIntType, &w);
+ CFNumberGetValue(imageHeight, kCFNumberIntType, &h);
+ CFNumberGetValue(DPIWidth, kCFNumberIntType, &hRes);
+ CFNumberGetValue(DPIHeight, kCFNumberIntType, &vRes);
+
+ bounds->x = 0;
+ bounds->y = 0;
+ bounds->wd = w * 72.27 / hRes;
+ bounds->ht = h * 72.27 / vRes;
+ CFRelease(properties);
+ CFRelease(picFileSource);
}
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_pic.c b/Build/source/texk/web2c/xetexdir/XeTeX_pic.c
index 9481dce5f54..a4ae4724da1 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeX_pic.c
+++ b/Build/source/texk/web2c/xetexdir/XeTeX_pic.c
@@ -33,7 +33,7 @@ authorization from the copyright holders.
/*
XeTeX_pic.c
interface between xetex and graphics files
- (not used on OS X -- we use QuickTime graphics importers instead)
+ (not used on OS X -- we use ImageIO graphics importers instead)
only needs to get image dimensions, not actually load/process the file
*/
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXswap.h b/Build/source/texk/web2c/xetexdir/XeTeXswap.h
index f51dd0d6101..ffdcc2e2a01 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXswap.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXswap.h
@@ -35,8 +35,8 @@ authorization from the copyright holders.
#include <unicode/platform.h> // ICU's platform.h defines U_IS_BIG_ENDIAN for us
-static inline UInt16
-SWAP16(const UInt16 p)
+static inline uint16_t
+SWAP16(const uint16_t p)
{
#if U_IS_BIG_ENDIAN
return p;
@@ -45,8 +45,8 @@ SWAP16(const UInt16 p)
#endif
}
-static inline UInt32
-SWAP32(const UInt32 p)
+static inline uint32_t
+SWAP32(const uint32_t p)
{
#if U_IS_BIG_ENDIAN
return p;
@@ -56,28 +56,28 @@ SWAP32(const UInt32 p)
}
#ifdef __cplusplus
-static inline UInt16
-SWAP(UInt16 p)
+static inline uint16_t
+SWAP(uint16_t p)
{
return SWAP16(p);
}
-static inline UInt32
-SWAP(UInt32 p)
+static inline uint32_t
+SWAP(uint32_t p)
{
return SWAP32(p);
}
-static inline SInt16
-SWAP(SInt16 p)
+static inline int16_t
+SWAP(int16_t p)
{
- return (SInt16)SWAP16((UInt16)p);
+ return (int16_t)SWAP16((uint16_t)p);
}
-static inline SInt32
-SWAP(SInt32 p)
+static inline int32_t
+SWAP(int32_t p)
{
- return (SInt32)SWAP32((UInt32)p);
+ return (int32_t)SWAP32((uint32_t)p);
}
#endif
diff --git a/Build/source/texk/web2c/xetexdir/am/xetex.am b/Build/source/texk/web2c/xetexdir/am/xetex.am
index e2665c2ab24..eef92eb9a09 100644
--- a/Build/source/texk/web2c/xetexdir/am/xetex.am
+++ b/Build/source/texk/web2c/xetexdir/am/xetex.am
@@ -33,7 +33,7 @@ xetex_dependencies += $(ICU_DEPEND) $(TECKIT_DEPEND) $(HARFBUZZ_DEPEND) $(GRAPHI
if XETEX_MACOSX
xetex_cppflags += -DXETEX_MAC
-xetex_LDFLAGS = -framework Carbon -framework Cocoa -framework QuickTime
+xetex_LDFLAGS = -framework ApplicationServices -framework Cocoa
else !XETEX_MACOSX
diff --git a/Build/source/texk/web2c/xetexdir/pdfimage.cpp b/Build/source/texk/web2c/xetexdir/pdfimage.cpp
index 51b740ea06d..8b3a9e3ba09 100644
--- a/Build/source/texk/web2c/xetexdir/pdfimage.cpp
+++ b/Build/source/texk/web2c/xetexdir/pdfimage.cpp
@@ -32,12 +32,6 @@ authorization from the copyright holders.
#include "pdfimage.h"
-#include <dirent.h>
-#include <poppler-config.h>
-#include <goo/GooString.h>
-#include <goo/gmem.h>
-#include <goo/gfile.h>
-
#include "PDFDoc.h"
#include "Catalog.h"
#include "Page.h"
diff --git a/Build/source/texk/web2c/xetexdir/trans.c b/Build/source/texk/web2c/xetexdir/trans.c
index 9e2ab0e5b70..405347756b8 100644
--- a/Build/source/texk/web2c/xetexdir/trans.c
+++ b/Build/source/texk/web2c/xetexdir/trans.c
@@ -34,78 +34,54 @@ authorization from the copyright holders.
void makeidentity(transform* t)
{
-#ifdef XETEX_MAC
- *t = CGAffineTransformMake(1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
-#else
t->a = 1.0;
t->b = 0.0;
t->c = 0.0;
t->d = 1.0;
t->x = 0.0;
t->y = 0.0;
-#endif
}
void makescale(transform* t, double xscale, double yscale)
{
-#ifdef XETEX_MAC
- *t = CGAffineTransformMakeScale(xscale, yscale);
-#else
t->a = xscale;
t->b = 0.0;
t->c = 0.0;
t->d = yscale;
t->x = 0.0;
t->y = 0.0;
-#endif
}
void maketranslation(transform* t, double dx, double dy)
{
-#ifdef XETEX_MAC
- *t = CGAffineTransformMakeTranslation(dx, dy);
-#else
t->a = 1.0;
t->b = 0.0;
t->c = 0.0;
t->d = 1.0;
t->x = dx;
t->y = dy;
-#endif
}
#include <stdio.h>
void makerotation(transform* t, double a)
{
-#ifdef XETEX_MAC
- *t = CGAffineTransformMakeRotation(a);
-#else
t->a = cos(a);
t->b = sin(a);
t->c = -sin(a);
t->d = cos(a);
t->x = 0.0;
t->y = 0.0;
-#endif
}
void transformpoint(realpoint* p, const transform* t)
{
-#ifdef XETEX_MAC
- CGPoint r = CGPointApplyAffineTransform(*(CGPoint*)p, *t);
- *p = *(realpoint*)&r;
-#else
realpoint r;
r.x = t->a * p->x + t->c * p->y + t->x;
r.y = t->b * p->x + t->d * p->y + t->y;
*p = r;
-#endif
}
void transformconcat(transform* t1, const transform* t2)
{
-#ifdef XETEX_MAC
- *t1 = CGAffineTransformConcat(*t1, *t2);
-#else
transform r;
r.a = t1->a * t2->a + t1->b * t2->c + 0.0 * t2->x;
r.b = t1->a * t2->b + t1->b * t2->d + 0.0 * t2->y;
@@ -114,5 +90,4 @@ void transformconcat(transform* t1, const transform* t2)
r.x = t1->x * t2->a + t1->y * t2->c + 1.0 * t2->x;
r.y = t1->x * t2->b + t1->y * t2->d + 1.0 * t2->y;
*t1 = r;
-#endif
}
diff --git a/Build/source/texk/web2c/xetexdir/trans.h b/Build/source/texk/web2c/xetexdir/trans.h
index 88facea6d63..fa5957c62db 100644
--- a/Build/source/texk/web2c/xetexdir/trans.h
+++ b/Build/source/texk/web2c/xetexdir/trans.h
@@ -33,14 +33,6 @@ authorization from the copyright holders.
#ifndef _TRANS_H_
#define _TRANS_H_
-#ifdef XETEX_MAC
-
-#include <Carbon/Carbon.h>
-
-typedef CGAffineTransform transform;
-
-#else
-
#include <math.h>
/* apparently M_PI isn't defined by <math.h> under VC++ */
#ifndef M_PI
@@ -56,8 +48,6 @@ typedef struct {
double y;
} transform;
-#endif
-
typedef struct {
float x;
float y;
@@ -80,13 +70,6 @@ typedef struct {
#define bField(t) (t).b
#define cField(t) (t).c
#define dField(t) (t).d
-#ifdef XETEX_MAC /* transform fields have different names */
-#define txField(t) (t).tx
-#define tyField(t) (t).ty
-#else
-#define txField(t) (t).x
-#define tyField(t) (t).y
-#endif
#define xField(t) (t).x
#define yField(t) (t).y
diff --git a/Build/source/texk/web2c/xetexdir/xetex.defines b/Build/source/texk/web2c/xetexdir/xetex.defines
index c854df94519..4ad5cd2abf9 100644
--- a/Build/source/texk/web2c/xetexdir/xetex.defines
+++ b/Build/source/texk/web2c/xetexdir/xetex.defines
@@ -170,8 +170,6 @@ authorization from the copyright holders.
@define function dField();
@define function xField();
@define function yField();
-@define function txField();
-@define function tyField();
@define function wdField();
@define function htField();
@define function applymapping();
diff --git a/Build/source/texk/web2c/xetexdir/xetex.h b/Build/source/texk/web2c/xetexdir/xetex.h
index b159a5668ef..5e990bc7c05 100644
--- a/Build/source/texk/web2c/xetexdir/xetex.h
+++ b/Build/source/texk/web2c/xetexdir/xetex.h
@@ -114,12 +114,6 @@ authorization from the copyright holders.
#undef Xchr
#define Xchr(x) (x)
-#ifdef XETEX_MAC
-#undef input /* this is defined in texmfmp.h, but we don't need it and it confuses the carbon headers */
-#undef output
-#include <Carbon/Carbon.h> /* for Mac OS X, it's handy to have the Carbon APIs available */
-#endif
-
#include "trans.h" /* functions for affine transform operations */
#include <teckit/TECkit_Common.h> /* include this before XeTeX_ext.h */
#include "XeTeX_ext.h" /* other extension functions */
diff --git a/Build/source/texk/web2c/xetexdir/xetex.web b/Build/source/texk/web2c/xetexdir/xetex.web
index d368c3e4596..0f08195561a 100644
--- a/Build/source/texk/web2c/xetexdir/xetex.web
+++ b/Build/source/texk/web2c/xetexdir/xetex.web
@@ -142,6 +142,7 @@
% been a ``labor of love'' and the author hopes that users enjoy it.
% Here is TeX material that gets inserted after \input webmac
+\input xetexwebmac
\def\hang{\hangindent 3em\noindent\ignorespaces}
\def\hangg#1 {\hang\hbox{#1 }}
\def\textindent#1{\hangindent2.5em\noindent\hbox to2.5em{\hss#1 }\ignorespaces}
@@ -7135,8 +7136,7 @@ together with the corresponding |primitive| calls.
@d chr_cmd(#)==begin print(#);
if chr_code < @"10000 then print_ASCII(chr_code)
- {non-Plane 0 Unicodes can't be sent through |print_ASCII|}
- else begin print("number "); print_hex(chr_code) end;
+ else print_char(chr_code); {non-Plane 0 Unicodes can't be sent through |print_ASCII|}
end
@<Declare the procedure called |print_cmd_chr|@>=
@@ -12706,10 +12706,7 @@ begin if tracing_lost_chars>0 then
print_nl("Missing character: There is no ");
@.Missing character@>
if c < @"10000 then print_ASCII(c)
- else begin { non-Plane 0 Unicodes can't be sent through |print_ASCII| }
- print("character number ");
- print_hex(c);
- end;
+ else print_char(c); {non-Plane 0 Unicodes can't be sent through |print_ASCII|}
print(" in font ");
slow_print(font_name[f]); print_char("!"); end_diagnostic(false);
end;
@@ -13876,8 +13873,8 @@ end;
@ Extra stuff for justifiable AAT text; need to merge runs of words and normal spaces.
-@d is_native_word_node(#) == ((not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = native_word_node))
-@d is_glyph_node(#) == ((not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = glyph_node))
+@d is_native_word_node(#) == (((#)<>null and (not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = native_word_node)))
+@d is_glyph_node(#) == (((#)<>null and (not is_char_node(#)) and (type(#) = whatsit_node) and (subtype(#) = glyph_node)))
@<Merge sequences of words using AAT fonts and inter-word spaces into single nodes@>=
p := list_ptr(this_box);
@@ -13897,7 +13894,7 @@ check_next:
{found a normal space; if the next node is another word in the same font, we'll merge}
q := link(q);
@<Advance |q| past ignorable nodes@>;
- if (q <> null) and is_native_word_node(q) and (native_font(q) = native_font(r)) then begin
+ if is_native_word_node(q) and (native_font(q) = native_font(r)) then begin
p := q; {record new tail of run in |p|}
k := k + 1 + native_length(q);
q := link(q);
@@ -13905,7 +13902,7 @@ check_next:
end;
goto end_node_run;
end;
- if (q <> null) and is_native_word_node(q) and (native_font(q) = native_font(r)) then begin
+ if is_native_word_node(q) and (native_font(q) = native_font(r)) then begin
p := q; {record new tail of run in |p|}
q := link(q);
goto check_next;
@@ -15383,8 +15380,11 @@ fraction_noad:@<Display fraction noad |p|@>;
@<Declare procedures needed for displaying the elements of mlists@>=
procedure print_fam_and_char(@!p:pointer); {prints family and character}
+var c:integer;
begin print_esc("fam"); print_int(fam(p) mod @"100); print_char(" ");
-print_ASCII(qo(character(p)) + (fam(p) div @"100) * @"10000);
+c:=(cast_to_ushort(character(p)) + ((plane_and_fam_field(p) div @"100) * @"10000));
+if c < @"10000 then print_ASCII(c)
+else print_char(c); {non-Plane 0 Unicodes can't be sent through |print_ASCII|}
end;
@#
procedure print_delimiter(@!p:pointer); {prints a delimiter as 24-bit hex value}
@@ -16995,8 +16995,11 @@ if x<>null then begin
@<Switch to a larger native-font accent if available and appropriate@>;
{determine horiz positioning}
- sa:=get_ot_math_accent_pos(f,native_glyph(p));
- if sa=@"7FFFFFFF then sa:=half(width(y));
+ if is_glyph_node(p) then
+ begin sa:=get_ot_math_accent_pos(f,native_glyph(p));
+ if sa=@"7FFFFFFF then sa:=half(width(y));
+ end
+ else sa:=half(width(y));
if is_bottom_acc(q) or (s=@"7FFFFFFF) then s:=half(w);
shift_amount(y):=s-sa;
end else
@@ -17492,7 +17495,7 @@ var p,@!s,@!x,@!y,@!z:pointer; {temporary registers for box construction}
@!t:integer; {subsidiary size code}
@!save_f:internal_font_number;
begin p:=new_hlist(q);
-if is_char_node(p) or (p<>null and is_glyph_node(p)) then
+if is_char_node(p) or is_glyph_node(p) then
begin shift_up:=0; shift_down:=0;
end
else begin z:=hpack(p,natural);
@@ -17603,11 +17606,14 @@ The following definitions should be kept in sync with \.{XeTeXOTMath.cpp}.
@<Attach subscript OpenType math kerning@>=
begin save_f:=cur_f;@/
fetch(subscr(q));
+sub_kern:=0; g:=0;
if is_new_mathfont(cur_f) then begin
s:=new_native_character(cur_f, qo(cur_c));
g:=get_native_glyph(s, 0);
end;
-sub_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sub_cmd, shift_down);
+if is_glyph_node(p) then
+ sub_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sub_cmd, shift_down);
+
if sub_kern<>0 then p:=attach_hkern_to_new_hlist(q, sub_kern);
cur_f:=save_f;
end;
@@ -17615,11 +17621,14 @@ end;
@ @<Attach superscript OpenType math kerning@>=
begin save_f:=cur_f;@/
fetch(supscr(q));
+sup_kern:=0; g:=0;
if is_new_mathfont(cur_f) then begin
s:=new_native_character(cur_f, qo(cur_c));
g:=get_native_glyph(s, 0);
end;
-sup_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sup_cmd, shift_up);
+if is_glyph_node(p) then
+ sup_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sup_cmd, shift_up);
+
if (sup_kern<>0) and (math_type(subscr(q))=empty) then
{if there is a superscript the kern will be added to |shift_amount(x)|}
p:=attach_hkern_to_new_hlist(q, sup_kern);
@@ -26610,7 +26619,10 @@ char_given: begin print_esc("char"); print_hex(chr_code);
end;
math_given: begin print_esc("mathchar"); print_hex(chr_code);
end;
-XeTeX_math_given: begin print_esc("Umathchar"); print_hex(chr_code);
+XeTeX_math_given: begin print_esc("Umathchar");
+ print_hex(math_class_field(chr_code));
+ print_hex(math_fam_field(chr_code));
+ print_hex(math_char_field(chr_code));
end;
@ We temporarily define |p| to be |relax|, so that an occurrence of |p|
@@ -28902,7 +28914,7 @@ begin
end
else if (type(pp) = disc_node) then begin
ppp := link(pp);
- if (ppp <> null) and is_native_word_node(ppp)
+ if is_native_word_node(ppp)
and (native_font(ppp) = native_font(p)) then begin
pp := link(ppp);
goto restart;
@@ -29535,8 +29547,8 @@ begin
pic_transform2(tail) := D2Fix(bField(t));
pic_transform3(tail) := D2Fix(cField(t));
pic_transform4(tail) := D2Fix(dField(t));
- pic_transform5(tail) := D2Fix(txField(t));
- pic_transform6(tail) := D2Fix(tyField(t));
+ pic_transform5(tail) := D2Fix(xField(t));
+ pic_transform6(tail) := D2Fix(yField(t));
memcpy(addressof(mem[tail + pic_node_size]), pic_path, strlen(pic_path));
libc_free(pic_path);
diff --git a/Build/source/texk/web2c/xetexdir/xetexwebmac.tex b/Build/source/texk/web2c/xetexdir/xetexwebmac.tex
new file mode 100644
index 00000000000..771d58df240
--- /dev/null
+++ b/Build/source/texk/web2c/xetexdir/xetexwebmac.tex
@@ -0,0 +1,255 @@
+% standard macros for WEB listings (in addition to PLAIN.TEX)
+%
+% pdfTeX adjustments mainained by Han The Thanh <hanthethanh@gmx.net>.
+% XeTeX adjustments mainited by Khaled Hosny <khaledhosny@eglug.org>
+%
+\xdef\fmtversion{\fmtversion+WEBMAC4.1} % identifies current set of macros
+\parskip 0pt % no stretch between paragraphs
+\parindent 1em % for paragraphs and for the first line of Pascal text
+
+\font\eightrm=cmr8 \let\sc=\eightrm % NOT a caps-and-small-caps font!
+\let\mainfont=\tenrm
+\font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
+\font\tentex=cmtex10 % TeX extended character set (used in strings)
+\fontdimen7\tentex=0pt % no extra space after punctuation
+
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\|#1{\hbox{$#1$}} % one-letter identifiers look a bit better this way
+\def\&#1{\hbox{\bf#1\/}} % boldface type for reserved words
+\def\.#1{\hbox{\tentex % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\'=\RQ % right quote in a string
+ \let\`=\LQ % left quote in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ #1}}
+\def\#{\hbox{\tt\char`\#}} % parameter sign
+\def\${\hbox{\tt\char`\$}} % dollar sign
+\def\%{\hbox{\tt\char`\%}} % percent sign
+\def\^{\ifmmode\mathchar"222 \else\char`^ \fi} % pointer or hat
+% circumflex accents can be obtained from \^^D instead of \^
+\def\AT!{@} % at sign for control text
+
+\chardef\AM=`\& % ampersand character in a string
+\chardef\BS=`\\ % backslash in a string
+\chardef\LB=`\{ % left brace in a string
+\def\LQ{{\tt\char'22}} % left quote in a string
+\chardef\RB=`\} % right brace in a string
+\def\RQ{{\tt\char'23}} % right quote in a string
+\def\SP{{\tt\char`\ }} % (visible) space in a string
+\chardef\TL=`\~ % tilde in a string
+\chardef\UL=`\_ % underline character in a string
+
+\newbox\bak \setbox\bak=\hbox to -1em{} % backspace one em
+\newbox\bakk\setbox\bakk=\hbox to -2em{} % backspace two ems
+
+\newcount\ind % current indentation in ems
+\def\1{\global\advance\ind by1\hangindent\ind em} % indent one more notch
+\def\2{\global\advance\ind by-1} % indent one less notch
+\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+\def\4{\copy\bak} % backspace one notch
+\def\5{\hfil\penalty-1\hfilneg\kern2.5em\copy\bakk\ignorespaces}% optional break
+\def\6{\ifmmode\else\par % forced break
+ \hangindent\ind em\noindent\kern\ind em\copy\bakk\ignorespaces\fi}
+\def\7{\Y\6} % forced break and a little extra space
+
+\let\yskip=\smallskip
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+% Some changes for xetex
+\def\note#1#2.{\Y\noindent{\hangindent2em\baselineskip10pt\eightrm#1~\pdfnote#2..\par}}
+
+\def\linkcolor#1{\special{color push rgb 0.4 0.6 1.0}#1\special{color pop}}
+\def\link#1#2{\special{pdf:bann<</Type/Annot/Subtype/Link/Border[0 0 0]/A<</S/GoTo/D(#1)>>>>}\linkcolor{#2}\special{pdf:eann}}
+
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newcount\countA
+\countA=0
+\def\pdfnote#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}\maketoks}\the\toksA}
+\def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+\def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+\def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+\def\maketoks{%
+ \expandafter\poptoks\the\toksA|ENDTOKS|
+ \ifx\first0\adn0
+ \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+ \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+ \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+ \else
+ \ifnum0=\countA\else\makenote\fi
+ \ifx\first.\let\next=\done\else
+ \let\next=\maketoks
+ \addtokens{\toksB}{\the\toksD}
+ \ifx\first,\addtokens{\toksB}{\space}\fi
+ \fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next
+}
+\def\n#1{\link{#1}{#1}}
+\def\makenote{\addtokens{\toksB}%
+ {\noexpand\n{\the\toksC}}\toksC={}\global\countA=0}
+\def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+
+\def\lapstar{\rlap{*}}
+\def\startsection{\Q{\let\*=\empty\special{pdf:dest (\modstar) [@thispage /XYZ @xpos @ypos null]}}%
+ \noindent{\let\*=\lapstar\bf\modstar.\quad}}
+\def\defin#1{\global\advance\ind by 2 \1\&{#1 }} % begin `define' or `format'
+\def\A{\note{See also section}} % crossref for doubly defined section name
+\def\As{\note{See also sections}} % crossref for multiply defined section name
+\def\B{\mathopen{\.{@\{}}} % begin controlled comment
+\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % Pascal comments
+ \XX\hfil\penalty-1\hfilneg\quad$\{\,$#1$\,\}$\XX}
+\def\D{\defin{define}} % macro definition
+\def\E{\cdot10^} % exponent in floating point constant
+\def\ET{ and~} % conjunction between two section numbers
+\def\ETs{, and~} % conjunction between the last two of several section numbers
+\def\F{\defin{format}} % format definition
+\let\G=\ge % greater than or equal sign
+\def\H#1{\hbox{\rm\char"7D\tt#1}} % hexadecimal constant
+\let\I=\ne % unequal sign
+\def\J{\.{@\&}} % TANGLE's join operation
+\let\K=\gets % left arrow
+\let\L=\le % less than or equal sign
+\outer\def\M#1.{\MN#1.\ifon\vfil\penalty-100\vfilneg % beginning of section
+ \vskip12ptminus3pt\startsection\ignorespaces}
+\outer\def\N#1.#2.{\MN#1.\vfil\eject % beginning of starred section
+ \def\rhead{\uppercase{\ignorespaces#2}} % define running headline
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\Z{#2}{\modno}{\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces#2.\quad}\ignorespaces}
+\def\MN#1.{\par % common code for \M, \N
+ {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}
+ \ifx\modno\modstar \onmaybe \else\ontrue \fi \mark{\modno}}
+\def\O#1{\hbox{\rm\char'23\kern-.2em\it#1\/\kern.05em}} % octal constant
+\def\P{\rightskip=0pt plus 100pt minus 10pt % go into Pascal mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \global\ind=2 \1\ \unskip}
+\def\Q{\rightskip=0pt % get out of Pascal mode
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50 }
+\let\R=\lnot % logical not
+\let\S=\equiv % equivalence sign
+\def\T{\mathclose{\.{@\}}}} % terminate controlled comment
+\def\U{\note{This code is used in section}} % crossref for use of a section
+\def\Us{\note{This code is used in sections}} % crossref for uses of a section
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
+ \XX$\langle\,$#2{\eightrm\kern.5em\pdfnote#1.}$\,\rangle$\XX}
+\def\Y{\par\yskip}
+\let\Z=\let % now you can \send the control sequence \Z
+\def\){\hbox{\.{@\$}}} % sign for string pool check sum
+\def\]{\hbox{\.{@\\}}} % sign for forced line break
+\def\=#1{\kern2pt\hbox{\vrule\vtop{\vbox{\hrule
+ \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+ \hrule}\vrule}\kern2pt} % verbatim string
+\let\~=\ignorespaces
+\let\*=*
+
+\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue
+\newif\ifon \newif\iftitle \newif\ifpagesaved
+\def\lheader{\mainfont\the\pageno\eightrm\qquad\rhead\hfill\title\qquad
+ \tensy x\mainfont\topmark} % top line on left-hand pages
+\def\rheader{\tensy x\mainfont\topmark\eightrm\qquad\title\hfill\rhead
+ \qquad\mainfont\the\pageno} % top line on right-hand pages
+\def\page{\box255 }
+\def\normaloutput#1#2#3{\ifodd\pageno\hoffset=\pageshift\fi
+ \shipout\vbox{
+ \vbox to\fullpageheight{
+ \iftitle\global\titlefalse
+ \else\hbox to\pagewidth{\vbox to10pt{}\ifodd\pageno #3\else#2\fi}\fi
+ \vfill#1}} % parameter #1 is the page itself
+ \global\advance\pageno by1}
+
+\def\rhead{\.{WEB} OUTPUT} % this running head is reset by starred sections
+\def\title{} % an optional title can be set by the user
+\def\topofcontents{\centerline{\titlefont\title}
+ \vfill} % this material will start the table of contents page
+\def\botofcontents{\vfill} % this material will end the table of contents page
+\def\contentspagenumber{0} % default page number for table of contents
+\newdimen\pagewidth \pagewidth=6.5in % the width of each page
+\newdimen\pageheight \pageheight=8.7in % the height of each page
+\newdimen\fullpageheight \fullpageheight=9in % page height including headlines
+\newdimen\pageshift \pageshift=0in % shift righthand pages wrt lefthand ones
+\def\magnify#1{\mag=#1\pagewidth=6.5truein\pageheight=8.7truein
+ \fullpageheight=9truein\setpage}
+\def\setpage{\hsize\pagewidth\vsize\pageheight} % use after changing page size
+\def\contentsfile{CONTENTS} % file that gets table of contents info
+\def\readcontents{\input CONTENTS}
+
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \global\output{\normaloutput\page\lheader\rheader}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+
+\def\ch{\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+\newbox\sbox % saved box preceding the index
+\newbox\lbox % lefthand column in the index
+\def\inx{\par\vskip6pt plus 1fil % we are beginning the index
+ \write\cont{} % ensure that the contents file isn't empty
+ \closeout\cont % the contents information has been fully gathered
+ \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
+ \global\setbox\sbox=\page \global\pagesavedtrue}
+ \pagesavedfalse \eject % eject the page-so-far and predecessors
+ \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+ \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
+ \hsize=.5\pagewidth \advance\hsize by -10pt
+ % column width for the index (20pt between cols)
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+ \def\lr{L} % this tells whether the left or right column is next
+ \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
+ \else\normaloutput{\vbox to\pageheight{\box\sbox\vss
+ \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader
+ \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+ \message{Index:}
+ \parskip 0pt plus .5pt
+ \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em\pdfnote} % index entry
+ \let\ttentry=\. \def\.##1{\ttentry{##1\kern.2em}} % give \tt a little room
+ \def\[##1]{$\underline{##1}$} % underlined index item
+ \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar
+ \hyphenpenalty 10000 \parindent0pt}
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \parfillskip 0pt plus 1fil
+ \def\rhead{NAMES OF THE SECTIONS}
+ \message{Section names:}
+ \output{\normaloutput\page\lheader\rheader}
+ \setpage
+ \def\note##1##2.{\hfil\penalty-1\hfilneg\quad{\eightrm##1~\pdfnote##2..}}
+ \linepenalty=10 % try to conserve lines
+ \def\U{\note{Used in section}} % crossref for use of a section
+ \def\Us{\note{Used in sections}} % crossref for uses of a section
+ \def\:{\par\hangindent 2em}\let\*=*\let\.=\ttentry}
+\def\con{\par\vfill\eject % finish the section names
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage
+ \output{\normaloutput\page\lheader\rheader}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber \def\rhead{TABLE OF CONTENTS}
+ \message{Table of contents:}
+ \topofcontents
+ \line{\hfil Section\hbox to3em{\hss Page}}
+ \def\Z##1##2##3{\line{\link{##2}{\ignorespaces##1
+ \leaders\hbox to .5em{.\hfil}\hfil\ ##2}
+ \hbox to3em{\hss##3}}}
+ \readcontents\relax % read the contents info
+ \botofcontents \makeoutlines\end} % print the contents page(s) and terminate
+
+\newcount\countB
+\def\makeoutlines{%
+ \def\?##1]{}\def\Z##1##2##3{\special{pdf:out 1 <</Title(##1)/A<</S/GoTo/D(##2)>>>>}}
+ \input CONTENTS\relax}
+\endinput