On 07/12/2011 12:14 AM, Behdad Esfahbod wrote:
> It's a bug in HarfBuzz. Jonathan has fixed that in Mozilla, but I haven't
> adopted the fix upstream yet. It's a muddy area, there are many differently
> buggy fonts, and we need to work around them all. I'll take a look tonight.
>
Here's the current version of the hack from Mozilla, adapted to work
with mainline HarfBuzz-ng, in case anyone is interested. They still use
an older version of HarfBuzz for some reason.
This might be hacky but it works well for me. Fixes Arial, Arial Unicode
MS and Times New Roman, but doesn't break other fonts like DejaVu Sans
Mono (this was reported on Mozilla Bugzilla, IIRC).
Best regards,
Grigori
>From ad9eb27f801af59c432375ca79464d8fd66f9408 Mon Sep 17 00:00:00 2001
From: Grigori Goronzy <greg@blackbox>
Date: Tue, 12 Jul 2011 13:14:38 +0200
Subject: [PATCH] HACK: use zero advance for marks/diacritics
---
src/hb-ot-layout.cc | 21 ++++++++++++++++++++-
src/hb-ot-layout.h | 2 +-
src/hb-ot-shape.cc | 21 +++++++++++++++++++--
3 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index a49f339..9520255 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -35,6 +35,7 @@
#include "hb-ot-layout-gpos-private.hh"
#include "hb-ot-head-private.hh"
#include "hb-ot-maxp-private.hh"
+#include "hb-ot-shape-private.hh"
#include <stdlib.h>
@@ -489,8 +490,26 @@ hb_ot_layout_position_lookup (hb_font_t *font,
}
void
-hb_ot_layout_position_finish (hb_buffer_t *buffer)
+hb_ot_layout_position_finish (hb_face_t *face, hb_buffer_t *buffer)
{
+ /* force diacritics to have zero width */
+ unsigned int count = buffer->len;
+ if (hb_ot_layout_has_glyph_classes (face)) {
+ const GDEF& gdef = _get_gdef (face);
+ for (unsigned int i = 1; i < count; i++) {
+ if (gdef.get_glyph_class (buffer->info[i].codepoint) == GDEF::MarkGlyph) {
+ buffer->pos[i].x_advance = 0;
+ }
+ }
+ } else {
+ /* no GDEF classes available, so use General Category as a fallback */
+ for (unsigned int i = 1; i < count; i++) {
+ if (buffer->info[i].general_category() == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
+ buffer->pos[i].x_advance = 0;
+ }
+ }
+ }
+
GPOS::position_finish (buffer);
}
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 6320437..9666ba6 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -198,7 +198,7 @@ hb_ot_layout_position_lookup (hb_font_t *font,
/* Should be called after all the position_lookup's are done */
void
-hb_ot_layout_position_finish (hb_buffer_t *buffer);
+hb_ot_layout_position_finish (hb_face_t *face, hb_buffer_t *buffer);
HB_END_DECLS
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 8378e81..bce119e 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -170,7 +170,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
&c->buffer->pos[i].y_offset);
}
- hb_ot_layout_position_finish (c->buffer);
+ hb_ot_layout_position_finish (c->face, c->buffer);
c->applied_position_complex = TRUE;
return;
@@ -323,7 +323,24 @@ hb_position_default (hb_ot_shape_context_t *c)
static void
hb_position_complex_fallback (hb_ot_shape_context_t *c HB_UNUSED)
{
- /* TODO Mark pos */
+ unsigned int count = c->buffer->len;
+ if (c->buffer->props.direction == HB_DIRECTION_RTL) {
+ for (unsigned int i = 1; i < count; i++) {
+ unsigned int gen_cat = c->buffer->info[i].general_category();
+ if ((1<<gen_cat) & ((1<<HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)|(1<<HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK)|(1<<HB_UNICODE_GENERAL_CATEGORY_FORMAT))) {
+ c->buffer->pos[i].x_advance = 0;
+ }
+ }
+ } else {
+ for (unsigned int i = 1; i < count; i++) {
+ unsigned int gen_cat = c->buffer->info[i].general_category();
+ if ((1<<gen_cat) & ((1<<HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)|(1<<HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK)|(1<<HB_UNICODE_GENERAL_CATEGORY_FORMAT))) {
+ hb_glyph_position_t& pos = c->buffer->pos[i];
+ pos.x_offset = -pos.x_advance;
+ pos.x_advance = 0;
+ }
+ }
+ }
}
static void
--
1.7.2.3
_______________________________________________
HarfBuzz mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/harfbuzz