Pango kerning for Mac OS X

This commit is contained in:
Matthew Flatt 2012-05-17 15:48:45 -06:00
parent b7d5aed8d7
commit e0256bc9c7
5 changed files with 251 additions and 27 deletions

View File

@ -4,7 +4,7 @@
(provide do-download)
(define url-host "download.racket-lang.org")
(define url-path "/libs/7/")
(define url-path "/libs/8/")
(define url-base (string-append "http://" url-host url-path))
(define architecture #f) ;; set in `do-download'

View File

@ -33,7 +33,7 @@
["libglib-2.0.0.dylib" 1272192]
["libpango-1.0.0.dylib" 351672]
["libgmodule-2.0.0.dylib" 18820]
["libpangocairo-1.0.0.dylib" 83728]
["libpangocairo-1.0.0.dylib" 83928]
["libgobject-2.0.0.dylib" 308304]
["libpixman-1.0.dylib" 526716]
["libgthread-2.0.0.dylib" 12708]
@ -48,7 +48,7 @@
["libglib-2.0.0.dylib" 1689952]
["libpango-1.0.0.dylib" 392432]
["libgmodule-2.0.0.dylib" 19768]
["libpangocairo-1.0.0.dylib" 96352]
["libpangocairo-1.0.0.dylib" 96640]
["libgobject-2.0.0.dylib" 438192]
["libpixman-1.0.dylib" 633368]
["libgthread-2.0.0.dylib" 8592]

View File

@ -26,22 +26,14 @@ Patches:
#if defined(USE_LIBICONV_GNU) && !defined (_LIBICONV_H)
pango/pango/modules.c:573: change to
// read_modules ();
pango/modules/basic/basic-atsui.c:60: add
if (!glyph) { glyph = PANGO_GET_UNKNOWN_GLYPH(glyph); }
pango/modules/basic/basic-coretext.c:
apply "coretext.patch"
pango/pangocairo-atsuifont.c:141: add
metrics->underline_position = -metrics->underline_position;
pango_quantize_line_geometry (&metrics->underline_thickness,
&metrics->underline_position);
metrics->underline_position = -(metrics->underline_position
+ metrics->underline_thickness);
pango/pangocairo-coretextfont.c:150: add
metrics->underline_position = -metrics->underline_position;
pango_quantize_line_geometry (&metrics->underline_thickness,
&metrics->underline_position);
metrics->underline_position = -(metrics->underline_position
+ metrics->underline_thickness);
pango/modules/basic/basic-atsui.c,
pango/pangocairo-atsuifont.c,
pango/pangoatsui.h,
pango/pangoatsui.c:
apply "atsui.patch" (32-bit only)
pango/modules/basic/basic-coretext.c,
pango/pangocairo-coretextfont.c:
apply "coretext.patch" (64-bit only)
gettext/gettext-tools/gnulib-lib/stpncpy.c:28: may need to comment out
// # define __stpncpy stpncpy
PSMTabBarControl/PSMTabBarControl.m:216: change to

129
src/mac/atsui.patch Normal file
View File

@ -0,0 +1,129 @@
diff -r -u pango-1.29.5-orig/modules/basic/basic-atsui.c pango-1.29.5/modules/basic/basic-atsui.c
--- pango-1.29.5-orig/modules/basic/basic-atsui.c 2011-08-15 19:11:08.000000000 -0600
+++ pango-1.29.5/modules/basic/basic-atsui.c 2012-05-17 15:06:09.000000000 -0600
@@ -53,10 +53,13 @@
PangoGlyphString *glyphs,
int i,
int offset,
- PangoGlyph glyph)
+ PangoGlyph glyph,
+ ATSUTextLayout text_layout)
{
PangoRectangle logical_rect;
+ if (!glyph) { glyph = PANGO_GET_UNKNOWN_GLYPH(glyph); }
+
glyphs->glyphs[i].glyph = G_UNLIKELY (glyph == kATSDeletedGlyphcode) ?
PANGO_GLYPH_EMPTY : glyph;
@@ -64,9 +67,30 @@
glyphs->glyphs[i].geometry.y_offset = 0;
glyphs->log_clusters[i] = offset;
- pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
- glyphs->glyphs[i].geometry.width = logical_rect.width;
-}
+ if (text_layout) {
+ ATSTrapezoid bounds;
+ ItemCount actual;
+ double w;
+
+ ATSUGetGlyphBounds(text_layout,
+ 0, 0,
+ i,
+ 1,
+ kATSUseFractionalOrigins,
+ 1,
+ &bounds,
+ &actual);
+ w = (Fix2X(bounds.upperRight.x) - Fix2X(bounds.upperLeft.x));
+ glyphs->glyphs[i].geometry.width = w * PANGO_SCALE;
+ } else {
+ pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
+ glyphs->glyphs[i].geometry.width = logical_rect.width;
+ }
+}
+
+#ifndef DoubleToFixed
+# define DoubleToFixed(a) ((Fixed)((double) (a) * fixed1))
+#endif
static void
basic_engine_shape (PangoEngineShape *engine,
@@ -87,9 +111,10 @@
PangoATSUIFont *afont = PANGO_ATSUI_FONT (font);
ATSUStyle style;
ATSUFontID fontID;
- ATSUAttributeTag styleTags[] = { kATSUFontTag };
- ATSUAttributeValuePtr styleValues[] = { &fontID };
- ByteCount styleSizes[] = { sizeof (ATSUFontID) };
+ Fixed fontSize;
+ ATSUAttributeTag styleTags[] = { kATSUFontTag, kATSUSizeTag };
+ ATSUAttributeValuePtr styleValues[] = { &fontID, &fontSize };
+ ByteCount styleSizes[] = { sizeof (ATSUFontID), sizeof(Fixed) };
utf16 = g_utf8_to_utf16 (text, length, NULL, &n16, NULL);
@@ -101,6 +126,7 @@
err = ATSUCreateStyle(&style);
fontID = pango_atsui_font_get_atsfont (afont);
+ fontSize = DoubleToFixed((double)pango_atsui_font_get_size(afont) / PANGO_SCALE);
err = ATSUSetAttributes(style,
(ItemCount)(sizeof(styleTags) / sizeof(styleTags[0])),
@@ -133,11 +159,11 @@
if (pango_is_zero_width (wc))
{
- set_glyph (font, glyphs, i, p - text, PANGO_GLYPH_EMPTY);
+ set_glyph (font, glyphs, i, p - text, PANGO_GLYPH_EMPTY, NULL);
}
else
{
- set_glyph (font, glyphs, i, p - text, layout_records[i].glyphID);
+ set_glyph (font, glyphs, i, p - text, layout_records[i].glyphID, text_layout);
if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
{
diff -r -u pango-1.29.5-orig/pango/pangoatsui.c pango-1.29.5/pango/pangoatsui.c
--- pango-1.29.5-orig/pango/pangoatsui.c 2011-08-15 19:11:08.000000000 -0600
+++ pango-1.29.5/pango/pangoatsui.c 2012-05-17 15:06:23.000000000 -0600
@@ -229,3 +229,10 @@
return priv->font_ref;
}
+
+int pango_atsui_font_get_size (PangoATSUIFont *font)
+{
+ PangoATSUIFontPrivate *priv = font->priv;
+
+ return pango_font_description_get_size(priv->desc);
+}
diff -r -u pango-1.29.5-orig/pango/pangoatsui.h pango-1.29.5/pango/pangoatsui.h
--- pango-1.29.5-orig/pango/pangoatsui.h 2011-08-15 19:11:08.000000000 -0600
+++ pango-1.29.5/pango/pangoatsui.h 2012-05-17 15:06:27.000000000 -0600
@@ -71,6 +71,8 @@
CGFontRef pango_atsui_font_get_cgfont (PangoATSUIFont *font);
ATSFontRef pango_atsui_font_get_atsfont (PangoATSUIFont *font);
+int pango_atsui_font_get_size (PangoATSUIFont *font);
+
#endif /* PANGO_ENABLE_ENGINE || PANGO_ENABLE_BACKEND */
GType pango_atsui_font_get_type (void) G_GNUC_CONST;
diff -r -u pango-1.29.5-orig/pango/pangocairo-atsuifont.c pango-1.29.5/pango/pangocairo-atsuifont.c
--- pango-1.29.5-orig/pango/pangocairo-atsuifont.c 2011-08-15 19:11:08.000000000 -0600
+++ pango-1.29.5/pango/pangocairo-atsuifont.c 2012-02-13 09:33:45.000000000 -0700
@@ -136,6 +136,12 @@
metrics->strikethrough_position = metrics->ascent / 3;
metrics->strikethrough_thickness = ats_metrics.underlineThickness * cafont->size * PANGO_SCALE;
+ metrics->underline_position = -metrics->underline_position;
+ pango_quantize_line_geometry (&metrics->underline_thickness,
+ &metrics->underline_position);
+ metrics->underline_position = -(metrics->underline_position
+ + metrics->underline_thickness);
+
return metrics;
}

View File

@ -1,6 +1,13 @@
diff -r -u pango-1.29.5-orig/modules/basic/basic-coretext.c pango-1.29.5/modules/basic/basic-coretext.c
--- pango-1.29.5-orig/modules/basic/basic-coretext.c 2011-08-15 19:11:08.000000000 -0600
+++ pango-1.29.5/modules/basic/basic-coretext.c 2012-02-13 10:09:51.000000000 -0700
@@ -58,6 +58,8 @@
+++ pango-1.29.5/modules/basic/basic-coretext.c 2012-05-17 14:04:39.000000000 -0600
@@ -54,18 +54,26 @@
PangoGlyphString *glyphs,
int i,
int offset,
- PangoGlyph glyph)
+ PangoGlyph glyph,
+ const CGSize *adv)
{
PangoRectangle logical_rect;
@ -9,13 +16,30 @@
glyphs->glyphs[i].glyph = glyph;
glyphs->glyphs[i].geometry.x_offset = 0;
@@ -87,15 +89,15 @@
glyphs->glyphs[i].geometry.y_offset = 0;
glyphs->log_clusters[i] = offset;
- pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
- glyphs->glyphs[i].geometry.width = logical_rect.width;
+ if (adv) {
+ /* by using the advances array, we get kerning */
+ glyphs->glyphs[i].geometry.width = adv->width * PANGO_SCALE;
+ } else {
+ pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
+ glyphs->glyphs[i].geometry.width = logical_rect.width;
+ }
}
static void
@@ -87,15 +95,17 @@
CFArrayRef runs;
CTRunRef run;
CTRunStatus run_status;
- CFIndex i, glyph_count;
+ CFIndex i, glyph_count, num_runs, run_index, run_offset, run_glyph_count;
const CGGlyph *cgglyphs;
+ const CGSize *cgadvs;
+ int free_cgglyphs = 0, free_cgadvs = 0;
CFTypeRef keys[] = {
- (CFTypeRef) kCTFontAttributeName
@ -28,7 +52,16 @@
};
attributes = CFDictionaryCreate (kCFAllocatorDefault,
@@ -120,13 +122,20 @@
@@ -110,8 +120,6 @@
cstr = CFStringCreateWithCString (kCFAllocatorDefault, copy,
kCFStringEncodingUTF8);
- g_free (copy);
-
attstr = CFAttributedStringCreate (kCFAllocatorDefault,
cstr,
attributes);
@@ -120,13 +128,22 @@
runs = CTLineGetGlyphRuns (line);
@ -49,13 +82,15 @@
+ glyph_count += CTRunGetGlyphCount (run);
+ }
+
+ g_free (copy);
+
+ run_offset = 0;
+ run_index = 0;
+ run_glyph_count = 0;
p = text;
pango_glyph_string_set_size (glyphs, glyph_count);
@@ -135,10 +144,18 @@
@@ -135,10 +152,41 @@
for (i = 0; i < glyph_count; i++)
{
@ -69,13 +104,36 @@
+ run = CFArrayGetValueAtIndex (runs, run_index++);
+ run_glyph_count = CTRunGetGlyphCount (run);
+ run_status = CTRunGetStatus (run);
+
+ if (free_cgglyphs) {
+ free((void*)cgglyphs);
+ free_cgglyphs = 0;
+ }
+ cgglyphs = CTRunGetGlyphsPtr (run);
+ if (!cgglyphs) {
+ CFRange range = { 0, 0 };
+ cgglyphs = (CGGlyph *)malloc(run_glyph_count * sizeof(CGGlyph));
+ free_cgglyphs = 1;
+ CTRunGetGlyphs (run, range, (CGGlyph *)cgglyphs);
+ }
+
+ if (free_cgadvs) {
+ free((void*)cgadvs);
+ free_cgadvs = 0;
+ }
+ cgadvs = CTRunGetAdvancesPtr (run);
+ if (!cgadvs) {
+ CFRange range = { 0, 0 };
+ cgadvs = (CGSize *)malloc(run_glyph_count * sizeof(CGSize));
+ free_cgadvs = 1;
+ CTRunGetAdvances (run, range, (CGSize *)cgadvs);
+ }
+ }
+
wc = g_utf8_get_char (p);
if (analysis->level % 2)
@@ -147,11 +164,13 @@
@@ -147,11 +195,13 @@
if (run_status & kCTRunStatusRightToLeft)
{
@ -89,12 +147,57 @@
real_i = i;
prev_i = real_i - 1;
}
@@ -171,7 +190,7 @@
@@ -161,7 +211,7 @@
if (pango_is_zero_width (wc))
{
- set_glyph (font, glyphs, real_i, p - text, PANGO_GLYPH_EMPTY);
+ set_glyph (font, glyphs, real_i, p - text, PANGO_GLYPH_EMPTY, NULL);
}
else
{
@@ -171,7 +221,7 @@
if (result != PANGO_COVERAGE_NONE)
{
- set_glyph (font, glyphs, real_i, p - text, cgglyphs[real_i]);
+ set_glyph (font, glyphs, real_i, p - text, cgglyphs[run_real_i]);
+ set_glyph (font, glyphs, real_i, p - text, cgglyphs[run_real_i], cgadvs + run_real_i);
if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
{
@@ -196,13 +246,18 @@
else
{
set_glyph (font, glyphs, real_i, p - text,
- PANGO_GET_UNKNOWN_GLYPH (wc));
+ PANGO_GET_UNKNOWN_GLYPH (wc), NULL);
}
}
p = g_utf8_next_char (p);
}
+ if (free_cgglyphs)
+ free((void *)cgglyphs);
+ if (free_cgadvs)
+ free((void *)cgadvs);
+
CFRelease (line);
CFRelease (attstr);
CFRelease (cstr);
diff -r -u pango-1.29.5-orig/pango/pangocairo-coretextfont.c pango-1.29.5/pango/pangocairo-coretextfont.c
--- pango-1.29.5-orig/pango/pangocairo-coretextfont.c 2011-08-15 19:11:08.000000000 -0600
+++ pango-1.29.5/pango/pangocairo-coretextfont.c 2012-02-17 14:18:18.000000000 -0700
@@ -147,6 +147,12 @@
metrics->strikethrough_position = metrics->ascent / 3;
metrics->strikethrough_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE;
+ metrics->underline_position = -metrics->underline_position;
+ pango_quantize_line_geometry (&metrics->underline_thickness,
+ &metrics->underline_position);
+ metrics->underline_position = -(metrics->underline_position
+ + metrics->underline_thickness);
+
layout = pango_layout_new (context);
font_desc = pango_font_describe_with_absolute_size ((PangoFont *) font);
pango_layout_set_font_description (layout, font_desc);