From behdad at behdad.org Wed Nov 4 10:38:36 2009 From: behdad at behdad.org (Behdad Esfahbod) Date: Wed, 04 Nov 2009 13:38:36 -0500 Subject: [HarfBuzz] HarfBuzz HackFest report Message-ID: <4AF1CA2C.9050606@behdad.org> Hi all, Here's what I blogged today: Here is a quick update re HarfBuzz : During May and August I finished rewriting the OpenType Layout engine to use mmap()ed font files. This is in Pango 1.26.x already. Pango and fontconfig also received a lot more optimization love. That deserves a long and separate blogpost. The net result is that the text stack's *memory usage is considerably lower* now. *All this goodness will be in the upcoming Fedora 12*. In October, I attended the 33rd Internationalization and Unicode Conference in San Jose to present the free software text stack (slides ) as well as present and promote HarfBuzz (slides ). That was a very fruitful event and I received lots of interest from many major industry players. With the liberal license that we are releasing HarfBuzz under, we expect broad adoption, which is exactly what we are looking for. This week, Jonathan Kew and myself are having a small HarfBuzz HackFest here in Mozilla's Toronto office. Here's what we have got done so far: * Jonathan has a version of Firefox using harfbuzz-ng (the codename for the rewrite) that has advanced layout features controlable through CSS. Very very cool stuff. He updated it to the latest harfbuzz-ng code. * I ripped harfbuzz-ng out of the Pango tree and into a standalone module. Finally! Took a couple hours of git surgery plus ten minutes to put together an autotools build system. Git clone URL is this . The harfbuzz-ng-external branch in Pango uses that as an external module. The plan is to reach a stable 1.0 release of harfbuzz-ng before next stable GNOME and most probably, Pango will require harfbuzz unconditionally (that is, on all platforms). Note that harfbuzz is NOT tied to FreeType, so you can use it with any rasterizer you have around. * We fixed all portability issues Jonathan had faced when compiling harfbuzz-ng with MSVC. * Jonathan is working on the shaper side, while I'm working on the API and pulling it all together. * I added glue code for using harfbuzz-ng with glib, ICU, and FreeType. * Lots of API and design review. At the rate this is developing, by the end of the week we should have basic shaper (Latin, Cyrillic, CJK, ...) and Arabic+Syriac working perfectly and tackling Indic family. We're closer to 1.0 than you may think! -- Posted By behdad to McEs, A Hacker Life at 11/04/2009 11:55:00 AM From ed.trager at gmail.com Wed Nov 4 13:16:02 2009 From: ed.trager at gmail.com (Ed Trager) Date: Wed, 4 Nov 2009 16:16:02 -0500 Subject: [HarfBuzz] HarfBuzz HackFest report In-Reply-To: <4AF1CA2C.9050606@behdad.org> References: <4AF1CA2C.9050606@behdad.org> Message-ID: <416e2cf10911041316r7136eb66g11fa745607e5e98c@mail.gmail.com> Hi, Behdad, That's very exciting news! I also looked at Jonathan Kew's stuff on using advanced OpenType features in the Firefox beta -- very cool! I'm glad to see all the progress being made. Keep up the good work! Best - Ed On Wed, Nov 4, 2009 at 1:38 PM, Behdad Esfahbod wrote: > Hi all, > > Here's what I blogged today: > > Here is a quick update re HarfBuzz > : > > During May and August I finished rewriting the OpenType Layout engine to > use mmap()ed font files. This is in Pango 1.26.x already. Pango and > fontconfig also received a lot more optimization love. That deserves a > long and separate blogpost. The net result is that the text stack's > *memory usage is considerably lower* now. *All this goodness will be in > the upcoming Fedora 12*. > > In October, I attended the 33rd Internationalization and Unicode > Conference in San Jose > to present the free software text stack (slides > ) > as well as present and promote HarfBuzz (slides > ). > That was a very fruitful event and I received lots of interest from many > major industry players. With the liberal license that we are releasing > HarfBuzz under, we expect broad adoption, which is exactly what we are > looking for. > > This week, Jonathan Kew and myself are having a small HarfBuzz HackFest > here in Mozilla's Toronto office. Here's what we have got done so far: > > ? ? * Jonathan has a version of Firefox using harfbuzz-ng (the codename > ? ? ? for the rewrite) that has advanced layout features controlable > ? ? ? through CSS. Very very cool stuff. He updated it to the latest > ? ? ? harfbuzz-ng code. > > ? ? * I ripped harfbuzz-ng out of the Pango tree and into a standalone > ? ? ? module. Finally! Took a couple hours of git surgery plus ten > ? ? ? minutes to put together an autotools build system. Git clone URL > ? ? ? is this . The > ? ? ? harfbuzz-ng-external branch in Pango uses that as an external > ? ? ? module. The plan is to reach a stable 1.0 release of harfbuzz-ng > ? ? ? before next stable GNOME and most probably, Pango will require > ? ? ? harfbuzz unconditionally (that is, on all platforms). Note that > ? ? ? harfbuzz is NOT tied to FreeType, so you can use it with any > ? ? ? rasterizer you have around. > > ? ? * We fixed all portability issues Jonathan had faced when compiling > ? ? ? harfbuzz-ng with MSVC. > > ? ? * Jonathan is working on the shaper side, while I'm working on the > ? ? ? API and pulling it all together. > > ? ? * I added glue code for using harfbuzz-ng with glib, ICU, and FreeType. > > ? ? * Lots of API and design review. > > At the rate this is developing, by the end of the week we should have > basic shaper (Latin, Cyrillic, CJK, ...) and Arabic+Syriac working > perfectly and tackling Indic family. We're closer to 1.0 than you may > think! > > -- > Posted By behdad to McEs, A Hacker Life > at 11/04/2009 > 11:55:00 AM > _______________________________________________ > HarfBuzz mailing list > HarfBuzz at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/harfbuzz > From behdad at behdad.org Wed Nov 4 16:30:52 2009 From: behdad at behdad.org (Behdad Esfahbod) Date: Wed, 04 Nov 2009 19:30:52 -0500 Subject: [HarfBuzz] HarfBuzz HackFest report In-Reply-To: <9f43d19d0911041626y1c493d98t81a7ed6937e8d297@mail.gmail.com> References: <4AF1CA2C.9050606@behdad.org> <9f43d19d0911041626y1c493d98t81a7ed6937e8d297@mail.gmail.com> Message-ID: <4AF21CBC.2040506@behdad.org> Hi Evan, On 11/04/2009 07:26 PM, Evan Martin wrote: > On Wed, Nov 4, 2009 at 10:38 AM, Behdad Esfahbod wrote: >> At the rate this is developing, by the end of the week we should have >> basic shaper (Latin, Cyrillic, CJK, ...) and Arabic+Syriac working >> perfectly and tackling Indic family. We're closer to 1.0 than you may >> think! > > That is good news. Is it worth beginning work on porting WebKit to use this? Yes. In fact, 17..20 of December I'll attend the WebKitGtk hackfest to work on exactly that. We definitely should share the WebKit HarfBuzz code between various ports. > I notice git://git.freedesktop.org/~behdad/harfbuzz-ng seems to not > include some of the pieces you mentioned (ICU for example, but also > hb-shape is more or less empty) -- is there a different tree I should > be tracking to follow progress? No, that's the tree. I pushed now. Check hb-icu.[ch]. It's glue for using ICU Unicode Character Database with HarfBuzz. hb-shape is still empty. I'll get to populate that tomorrow I hope. That will kinda conclude the API. > One reason I'm eager to look at this is to be able to provide early > feedback as to how well proposed APIs will work. Sure. Since I know you recently joined the list, you may want to check this message: http://lists.freedesktop.org/archives/harfbuzz/2009-August/000359.html The API hasn't changed much since. > Do 1.0's plans include writing comments or docs on the API? :) Yes, indeed. I'll get to gtk-doc'ing it as soon as we have a complete API working. Thanks, behdad From evan at chromium.org Wed Nov 4 16:26:35 2009 From: evan at chromium.org (Evan Martin) Date: Wed, 4 Nov 2009 16:26:35 -0800 Subject: [HarfBuzz] HarfBuzz HackFest report In-Reply-To: <4AF1CA2C.9050606@behdad.org> References: <4AF1CA2C.9050606@behdad.org> Message-ID: <9f43d19d0911041626y1c493d98t81a7ed6937e8d297@mail.gmail.com> On Wed, Nov 4, 2009 at 10:38 AM, Behdad Esfahbod wrote: > At the rate this is developing, by the end of the week we should have > basic shaper (Latin, Cyrillic, CJK, ...) and Arabic+Syriac working > perfectly and tackling Indic family. We're closer to 1.0 than you may > think! That is good news. Is it worth beginning work on porting WebKit to use this? I notice git://git.freedesktop.org/~behdad/harfbuzz-ng seems to not include some of the pieces you mentioned (ICU for example, but also hb-shape is more or less empty) -- is there a different tree I should be tracking to follow progress? One reason I'm eager to look at this is to be able to provide early feedback as to how well proposed APIs will work. Do 1.0's plans include writing comments or docs on the API? :) From behdad at behdad.org Thu Nov 5 08:54:53 2009 From: behdad at behdad.org (Behdad Esfahbod) Date: Thu, 05 Nov 2009 11:54:53 -0500 Subject: [HarfBuzz] Complex text layout for WebKit In-Reply-To: References: Message-ID: <4AF3035D.7060607@behdad.org> Hi Ayman, Well, I know there are people in Google who have ported Webkit to use HarfBuzz. They are on this list even. I let them answer since I have no clue about what Android does. behdad On 10/03/2009 03:44 AM, Ayman Alsanad wrote: > Hello Behdad, > Hope you are doing well, I found your article about text rendering > excellent .. although I think it's a little bit complicated .. > especially for non expert in the field. > Have you thought to work on arabizing android? or more specifically > Webkit .. I've taken a glimpse over the source code from android .. and > I'm surprised why its not supported yet .. it has everything needed (at > least that's what I think) .. when you look at the source code you'll > find a detailed Bidi classes (check out Webkit Source code from Android > rep.) ... > Would really appreciate hearing from you. > Regards, > Ayman. From agl at google.com Thu Nov 5 10:22:38 2009 From: agl at google.com (Adam Langley) Date: Thu, 5 Nov 2009 10:22:38 -0800 Subject: [HarfBuzz] Complex text layout for WebKit In-Reply-To: <4AF3035D.7060607@behdad.org> References: <4AF3035D.7060607@behdad.org> Message-ID: On Thu, Nov 5, 2009 at 8:54 AM, Behdad Esfahbod wrote: > Well, I know there are people in Google who have ported Webkit to use > HarfBuzz. ?They are on this list even. ?I let them answer since I have no clue > about what Android does. Opps, thanks for highlighting this message Behdad. Indeed, Chromium on Linux uses Harfbuzz and the code is in upstream WebKit (platform/graphics/chromium). It's a bit of a hack but, thankfully, Evan is fixing up some of the sharp edges. The BiDi code in Android is shared across all WebKit ports. I don't know the state of complex text layout in Android at the moment. You should probably ask about that on the Android lists. If they wanted it, the Chromium Linux code would probably work for them. AGL From martin_hosken at sil.org Thu Nov 5 23:46:57 2009 From: martin_hosken at sil.org (Martin Hosken) Date: Fri, 6 Nov 2009 14:46:57 +0700 Subject: [HarfBuzz] not linking to libstdc++ Message-ID: <20091106144657.217724f3@sil-mh5.dallas.sil.org> Dear Behdad, I'm about to try adding graphite support as a contrib to harfbuzz-ng. Graphite itself is in C++ and so the linking code is going to have to bridge between C and C++. But I notice that you go to great lengths to ensure that harfbuzz doesn't link to libstdc++. I am wondering why this is the case. TIA, Yours, Martin From lars at kemper.freedesktop.org Fri Nov 6 02:57:47 2009 From: lars at kemper.freedesktop.org (Lars Knoll) Date: Fri, 6 Nov 2009 02:57:47 -0800 (PST) Subject: [HarfBuzz] harfbuzz: Branch 'master' - 5 commits Message-ID: <20091106105747.5A69910051@kemper.freedesktop.org> src/harfbuzz-arabic.c | 60 +++++++++++++++++++++- src/harfbuzz-impl.c | 4 - src/harfbuzz-indic.cpp | 127 +++++++++++++++++++++++++++++------------------- src/harfbuzz-shaper.cpp | 36 +++++++++++-- src/harfbuzz-shaper.h | 2 src/harfbuzz-stream.c | 2 tests/shaping/main.cpp | 125 +++++++++++++++++++++++++++++++++++++++++++---- 7 files changed, 284 insertions(+), 72 deletions(-) New commits: commit 797fe54d9ebbafb0cdc00705c008ea09e7ac1e9e Author: Lars Knoll Date: Fri Nov 6 11:56:44 2009 +0100 add N'Ko support to the arabic shaper Long outstanding bug report for Qt. See http://bugreports.qt.nokia.com/browse/QTBUG-1042 diff --git a/src/harfbuzz-arabic.c b/src/harfbuzz-arabic.c index 4d85c19..3837087 100644 --- a/src/harfbuzz-arabic.c +++ b/src/harfbuzz-arabic.c @@ -489,6 +489,56 @@ static void getArabicProperties(const unsigned short *chars, int len, HB_ArabicP */ } +static Joining getNkoJoining(unsigned short uc) +{ + if (uc < 0x7ca) + return JNone; + if (uc <= 0x7ea) + return JDual; + if (uc <= 0x7f3) + return JTransparent; + if (uc <= 0x7f9) + return JNone; + if (uc == 0x7fa) + return JCausing; + return JNone; +} + +static void getNkoProperties(const unsigned short *chars, int len, HB_ArabicProperties *properties) +{ + int lastPos = 0; + int i = 0; + + Joining j = getNkoJoining(chars[0]); + ArabicShape shape = joining_table[XIsolated][j].form2; + properties[0].justification = HB_NoJustification; + + for (i = 1; i < len; ++i) { + properties[i].justification = (HB_GetUnicodeCharCategory(chars[i]) == HB_Separator_Space) ? + ArabicSpace : ArabicNone; + + j = getNkoJoining(chars[i]); + + if (j == JTransparent) { + properties[i].shape = XIsolated; + continue; + } + + properties[lastPos].shape = joining_table[shape][j].form1; + shape = joining_table[shape][j].form2; + + + lastPos = i; + } + properties[lastPos].shape = joining_table[shape][JNone].form1; + + + /* + for (int i = 0; i < len; ++i) + qDebug("nko properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification); + */ +} + /* // The unicode to unicode shaping codec. // does only presentation forms B at the moment, but that should be enough for @@ -1012,7 +1062,10 @@ static HB_Bool arabicSyriacOpenTypeShape(HB_ShaperItem *item, HB_Bool *ot_ok) if (f + l + item->item.pos < item->stringLength) { ++l; } - getArabicProperties(uc+f, l, props); + if (item->item.script == HB_Script_Nko) + getNkoProperties(uc+f, l, props); + else + getArabicProperties(uc+f, l, props); for (i = 0; i < (int)item->num_glyphs; i++) { apply[i] = 0; @@ -1051,7 +1104,8 @@ HB_Bool HB_ArabicShape(HB_ShaperItem *item) HB_Bool haveGlyphs; HB_STACKARRAY(HB_UChar16, shapedChars, item->item.length); - assert(item->item.script == HB_Script_Arabic || item->item.script == HB_Script_Syriac); + assert(item->item.script == HB_Script_Arabic || item->item.script == HB_Script_Syriac + || item->item.script == HB_Script_Nko); #ifndef NO_OPENTYPE @@ -1065,7 +1119,7 @@ HB_Bool HB_ArabicShape(HB_ShaperItem *item) } #endif - if (item->item.script == HB_Script_Syriac) + if (item->item.script != HB_Script_Arabic) return HB_BasicShape(item); shapedString(item->string, item->stringLength, item->item.pos, item->item.length, shapedChars, &slen, diff --git a/src/harfbuzz-shaper.cpp b/src/harfbuzz-shaper.cpp index f92bb55..f3ec8e1 100644 --- a/src/harfbuzz-shaper.cpp +++ b/src/harfbuzz-shaper.cpp @@ -637,7 +637,9 @@ const HB_ScriptEngine HB_ScriptEngines[] = { // Runic { HB_BasicShape, 0 }, // Khmer - { HB_KhmerShape, HB_KhmerAttributes } + { HB_KhmerShape, HB_KhmerAttributes }, + // N'Ko + { HB_ArabicShape, 0} }; void HB_GetCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength, @@ -877,7 +879,9 @@ static const OTScripts ot_scripts [] = { // Runic { HB_MAKE_TAG('r', 'u', 'n', 'r'), 0 }, // Khmer - { HB_MAKE_TAG('k', 'h', 'm', 'r'), 1 } + { HB_MAKE_TAG('k', 'h', 'm', 'r'), 1 }, + // N'Ko + { HB_MAKE_TAG('n', 'k', 'o', ' '), 1 } }; enum { NumOTScripts = sizeof(ot_scripts)/sizeof(OTScripts) }; diff --git a/src/harfbuzz-shaper.h b/src/harfbuzz-shaper.h index d2357f4..f7c7714 100644 --- a/src/harfbuzz-shaper.h +++ b/src/harfbuzz-shaper.h @@ -62,6 +62,7 @@ typedef enum { HB_Script_Ogham, HB_Script_Runic, HB_Script_Khmer, + HB_Script_Nko, HB_Script_Inherited, HB_ScriptCount = HB_Script_Inherited /* @@ -102,7 +103,6 @@ typedef enum { HB_Script_Cuneiform = Common, HB_Script_Phoenician = Common, HB_Script_PhagsPa = Common, - HB_Script_Nko = Common */ } HB_Script; diff --git a/tests/shaping/main.cpp b/tests/shaping/main.cpp index 41f2dbb..12fa7c4 100644 --- a/tests/shaping/main.cpp +++ b/tests/shaping/main.cpp @@ -181,6 +181,7 @@ private slots: void sinhala(); void khmer(); + void nko(); void linearB(); }; @@ -1075,6 +1076,40 @@ void tst_QScriptEngine::khmer() } } +void tst_QScriptEngine::nko() +{ + { + FT_Face face = loadFace("DejaVuSans.ttf"); + if (face) { + const ShapeTable shape_table [] = { + { { 0x7ca, 0x0 }, + { 0x5c1, 0x0 } }, + { { 0x7ca, 0x7ca, 0x0 }, + { 0x14db, 0x14d9, 0x0 } }, + { { 0x7ca, 0x7fa, 0x7ca, 0x0 }, + { 0x14db, 0x5ec, 0x14d9, 0x0 } }, + { { 0x7ca, 0x7f3, 0x7ca, 0x0 }, + { 0x14db, 0x5e7, 0x14d9, 0x0 } }, + { { 0x7ca, 0x7f3, 0x7fa, 0x7ca, 0x0 }, + { 0x14db, 0x5e7, 0x5ec, 0x14d9, 0x0 } }, + { {0}, {0} } + }; + + + const ShapeTable *s = shape_table; + while (s->unicode[0]) { + QVERIFY( shaping(face, s, HB_Script_Nko) ); + ++s; + } + + FT_Done_Face(face); + } else { + QSKIP("couln't find DejaVuSans.ttf", SkipAll); + } + } +} + + void tst_QScriptEngine::linearB() { { commit e6636cadacf220785fca12b741b4587ff1ee42ec Author: Lars Knoll Date: Thu Nov 5 16:28:49 2009 +0100 fix bug with Malayalam Samvruthokaram. As reported on the mailing list on June 10, 2009 by Praveen A. diff --git a/src/harfbuzz-indic.cpp b/src/harfbuzz-indic.cpp index df447e6..3008fca 100644 --- a/src/harfbuzz-indic.cpp +++ b/src/harfbuzz-indic.cpp @@ -1746,6 +1746,10 @@ static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int ++pos; continue; } + if (script == HB_Script_Malayalam && state == Matra && uc[pos-1] == 0x0d41) { + ++pos; + continue; + } goto finish; case Nukta: if (state == Consonant) diff --git a/tests/shaping/main.cpp b/tests/shaping/main.cpp index 9b6aa31..41f2dbb 100644 --- a/tests/shaping/main.cpp +++ b/tests/shaping/main.cpp @@ -979,6 +979,8 @@ void tst_QScriptEngine::malayalam() { 0x5e, 0x34, 0x65, 0x0 } }, { { 0xd15, 0xd57, 0x0 }, { 0x34, 0x65, 0x0 } }, + { { 0xd1f, 0xd4d, 0xd1f, 0xd41, 0xd4d, 0x0 }, + { 0x69, 0x5b, 0x64, 0x0 } }, { {0}, {0} } }; commit e66916e33821e71ba19479c32108a2be8bb539b2 Author: Lars Knoll Date: Thu Nov 5 15:57:16 2009 +0100 fix shaping of assamese ra See http://bugreports.qt.nokia.com/browse/QTBUG-1802 diff --git a/src/harfbuzz-indic.cpp b/src/harfbuzz-indic.cpp index 48f4f90..df447e6 100644 --- a/src/harfbuzz-indic.cpp +++ b/src/harfbuzz-indic.cpp @@ -566,7 +566,7 @@ static const unsigned char indicPosition[0xe00-0x900] = { None, None, None, None, None, None, None, None, - None, None, None, None, + Below, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, @@ -1252,7 +1252,9 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv // farther than 3 consonants from the end of the syllable. // #### replace the HasReph property by testing if the feature exists in the font! if (form(*uc) == Consonant || (script == HB_Script_Bengali && form(*uc) == IndependentVowel)) { - beginsWithRa = (properties & HasReph) && ((len > 2) && *uc == ra && *(uc+1) == halant); + if ((properties & HasReph) && (len > 2) && + (*uc == ra || *uc == 0x9f0) && *(uc+1) == halant) + beginsWithRa = true; if (beginsWithRa && form(*(uc+2)) == Control) beginsWithRa = false; diff --git a/tests/shaping/main.cpp b/tests/shaping/main.cpp index a7ea417..9b6aa31 100644 --- a/tests/shaping/main.cpp +++ b/tests/shaping/main.cpp @@ -515,6 +515,12 @@ void tst_QScriptEngine::bengali() { 0x179, 0x151, 0x172, 0x0 } }, { { 0x995, 0x9c7, 0x9d7, 0x0 }, { 0x179, 0x151, 0x17e, 0x0 } }, + { { 0x9b0, 0x9cd, 0x9ad, 0x0 }, + { 0x168, 0x276, 0x0 } }, + { { 0x9f0, 0x9cd, 0x9ad, 0x0 }, + { 0x168, 0x276, 0x0 } }, + { { 0x9f1, 0x9cd, 0x9ad, 0x0 }, + { 0x191, 0x17d, 0x168, 0x0 } }, { {0}, {0} } }; @@ -652,6 +658,12 @@ void tst_QScriptEngine::bengali() { 0x01fe, 0x0 } }, { { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0x0 }, { 0x10b, 0x167, 0x0 } }, + { { 0x9b0, 0x9cd, 0x9ad, 0x0 }, + { 0xa1, 0x167, 0x0 } }, + { { 0x9f0, 0x9cd, 0x9ad, 0x0 }, + { 0xa1, 0x167, 0x0 } }, + { { 0x9f1, 0x9cd, 0x9ad, 0x0 }, + { 0x11c, 0xa1, 0x0 } }, { {0}, {0} } }; commit e8a057fb67a0242e5a125d8cb2c823ad63e01449 Author: Lars Knoll Date: Wed Nov 4 14:14:12 2009 +0100 correctly support decomposed forms of two or three part matras The indic shaping engine wasn't correctly determining syllable bondaries and shaping decomposed forms of two part matras. This fixes it and adds a set of unit tests for them. diff --git a/src/harfbuzz-indic.cpp b/src/harfbuzz-indic.cpp index 7104d2a..48f4f90 100644 --- a/src/harfbuzz-indic.cpp +++ b/src/harfbuzz-indic.cpp @@ -419,7 +419,7 @@ static const unsigned char indicForms[0xe00-0x900] = { Matra, Halant, Invalid, Invalid, Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, LengthMark, + Invalid, Invalid, Invalid, Matra, Invalid, Invalid, Invalid, Invalid, Invalid, Invalid, Invalid, Invalid, @@ -1050,62 +1050,59 @@ static const IndicOrdering * const indic_order[] = { // vowel matras that have to be split into two parts. static const unsigned short split_matras[] = { - // matra, split1, split2 + // matra, split1, split2, split3 // bengalis - 0x9cb, 0x9c7, 0x9be, - 0x9cc, 0x9c7, 0x9d7, + 0x9cb, 0x9c7, 0x9be, 0x0, + 0x9cc, 0x9c7, 0x9d7, 0x0, // oriya - 0xb48, 0xb47, 0xb56, - 0xb4b, 0xb47, 0xb3e, - 0xb4c, 0xb47, 0xb57, + 0xb48, 0xb47, 0xb56, 0x0, + 0xb4b, 0xb47, 0xb3e, 0x0, + 0xb4c, 0xb47, 0xb57, 0x0, // tamil - 0xbca, 0xbc6, 0xbbe, - 0xbcb, 0xbc7, 0xbbe, - 0xbcc, 0xbc6, 0xbd7, + 0xbca, 0xbc6, 0xbbe, 0x0, + 0xbcb, 0xbc7, 0xbbe, 0x0, + 0xbcc, 0xbc6, 0xbd7, 0x0, // telugu - 0xc48, 0xc46, 0xc56, + 0xc48, 0xc46, 0xc56, 0x0, // kannada - 0xcc0, 0xcbf, 0xcd5, - 0xcc7, 0xcc6, 0xcd5, - 0xcc8, 0xcc6, 0xcd6, - 0xcca, 0xcc6, 0xcc2, - 0xccb, 0xcca, 0xcd5, + 0xcc0, 0xcbf, 0xcd5, 0x0, + 0xcc7, 0xcc6, 0xcd5, 0x0, + 0xcc8, 0xcc6, 0xcd6, 0x0, + 0xcca, 0xcc6, 0xcc2, 0x0, + 0xccb, 0xcc6, 0xcc2, 0xcd5, // malayalam - 0xd4a, 0xd46, 0xd3e, - 0xd4b, 0xd47, 0xd3e, - 0xd4c, 0xd46, 0xd57, + 0xd4a, 0xd46, 0xd3e, 0x0, + 0xd4b, 0xd47, 0xd3e, 0x0, + 0xd4c, 0xd46, 0xd57, 0x0, // sinhala - 0xdda, 0xdd9, 0xdca, - 0xddc, 0xdd9, 0xdcf, - 0xddd, 0xddc, 0xdca, - 0xdde, 0xdd9, 0xddf, + 0xdda, 0xdd9, 0xdca, 0x0, + 0xddc, 0xdd9, 0xdcf, 0x0, + 0xddd, 0xdd9, 0xdcf, 0xdca, + 0xdde, 0xdd9, 0xddf, 0x0, 0xffff }; -static inline void splitMatra(unsigned short *reordered, int matra, int &len, int &base) +static inline void splitMatra(unsigned short *reordered, int matra, int &len) { unsigned short matra_uc = reordered[matra]; //qDebug("matra=%d, reordered[matra]=%x", matra, reordered[matra]); const unsigned short *split = split_matras; while (split[0] < matra_uc) - split += 3; + split += 4; assert(*split == matra_uc); ++split; - if (indic_position(*split) == Pre) { - reordered[matra] = split[1]; - memmove(reordered + 1, reordered, len*sizeof(unsigned short)); - reordered[0] = split[0]; - base++; - } else { - memmove(reordered + matra + 1, reordered + matra, (len-matra)*sizeof(unsigned short)); - reordered[matra] = split[0]; - reordered[matra+1] = split[1]; - } - len++; + int added_chars = split[2] == 0x0 ? 1 : 2; + + memmove(reordered + matra + added_chars, reordered + matra, (len-matra)*sizeof(unsigned short)); + reordered[matra] = split[0]; + reordered[matra+1] = split[1]; + if(added_chars == 2) + reordered[matra+2] = split[2]; + len += added_chars; } #ifndef NO_OPENTYPE @@ -1130,12 +1127,23 @@ static const HB_OpenTypeFeature indic_features[] = { // #define INDIC_DEBUG #ifdef INDIC_DEBUG -#define IDEBUG qDebug +#define IDEBUG hb_debug +#include + +static void hb_debug(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); // use variable arg list + vfprintf(stderr, msg, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + #else #define IDEBUG if(0) printf #endif -#ifdef INDIC_DEBUG +#if 0 //def INDIC_DEBUG static QString propertiesToString(int properties) { QString res; @@ -1386,12 +1394,12 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv // to be at the beginning of the syllable, so we just move // them there now. if (matra_position == Split) { - splitMatra(uc, matra, len, base); + splitMatra(uc, matra, len); // Handle three-part matras (0xccb in Kannada) matra_position = indic_position(uc[matra]); - if (matra_position == Split) - splitMatra(uc, matra, len, base); - } else if (matra_position == Pre) { + } + + if (matra_position == Pre) { unsigned short m = uc[matra]; while (matra--) uc[matra+1] = uc[matra]; @@ -1609,11 +1617,11 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv // halant always applies #ifdef INDIC_DEBUG - { - IDEBUG("OT properties:"); - for (int i = 0; i < len; ++i) - qDebug(" i: %s", ::propertiesToString(properties[i]).toLatin1().data()); - } +// { +// IDEBUG("OT properties:"); +// for (int i = 0; i < len; ++i) +// qDebug(" i: %s", ::propertiesToString(properties[i]).toLatin1().data()); +// } #endif // initialize @@ -1731,6 +1739,11 @@ static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int if (script == HB_Script_Bengali && pos == 1 && (uc[0] == 0x0985 || uc[0] == 0x098f)) break; + // Sinhala uses the Halant as a component of certain matras. Allow these, but keep the state on Matra. + if (script == HB_Script_Sinhala && state == Matra) { + ++pos; + continue; + } goto finish; case Nukta: if (state == Consonant) @@ -1741,12 +1754,16 @@ static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int break; // fall through case VowelMark: - if (state == Matra || state == IndependentVowel) + if (state == Matra || state == LengthMark || state == IndependentVowel) break; // fall through case Matra: if (state == Consonant || state == Nukta) break; + if (state == Matra) { + // ### needs proper testing for correct two/three part matras + break; + } // ### not sure if this is correct. If it is, does it apply only to Bengali or should // it work for all Indic languages? // the combination Independent_A + Vowel Sign AA is allowed. @@ -1762,6 +1779,10 @@ static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int goto finish; case LengthMark: + if (state == Matra) { + // ### needs proper testing for correct two/three part matras + break; + } case IndependentVowel: case Invalid: case Other: diff --git a/tests/shaping/main.cpp b/tests/shaping/main.cpp index 1a3ef4f..a7ea417 100644 --- a/tests/shaping/main.cpp +++ b/tests/shaping/main.cpp @@ -178,7 +178,7 @@ private slots: void telugu(); void kannada(); void malayalam(); - // sinhala missing + void sinhala(); void khmer(); void linearB(); @@ -510,6 +510,11 @@ void tst_QScriptEngine::bengali() { 0x151, 0x276, 0x172, 0x143, 0x0 } }, { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x983, 0x0 }, { 0x151, 0x276, 0x172, 0x144, 0x0 } }, + // test decomposed two parts matras + { { 0x995, 0x9c7, 0x9be, 0x0 }, + { 0x179, 0x151, 0x172, 0x0 } }, + { { 0x995, 0x9c7, 0x9d7, 0x0 }, + { 0x179, 0x151, 0x17e, 0x0 } }, { {0}, {0} } }; @@ -638,15 +643,15 @@ void tst_QScriptEngine::bengali() if (face) { const ShapeTable shape_table [] = { { { 0x09a8, 0x09cd, 0x09af, 0x0 }, - { 0x0192, 0x0 } }, + { 0x01ca, 0x0 } }, { { 0x09b8, 0x09cd, 0x09af, 0x0 }, - { 0x01d6, 0x0 } }, + { 0x020e, 0x0 } }, { { 0x09b6, 0x09cd, 0x09af, 0x0 }, - { 0x01bc, 0x0 } }, + { 0x01f4, 0x0 } }, { { 0x09b7, 0x09cd, 0x09af, 0x0 }, - { 0x01c6, 0x0 } }, + { 0x01fe, 0x0 } }, { { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0x0 }, - { 0xd3, 0x12f, 0x0 } }, + { 0x10b, 0x167, 0x0 } }, { {0}, {0} } }; @@ -823,8 +828,9 @@ void tst_QScriptEngine::telugu() { 0xe6, 0xb3, 0x83, 0x0 } }, { { 0xc15, 0xc4d, 0xc30, 0xc48, 0x0 }, { 0xe6, 0xb3, 0x9f, 0x0 } }, - { {0}, {0} } - + { { 0xc15, 0xc46, 0xc56, 0x0 }, + { 0xe6, 0xb3, 0x0 } }, + { {0}, {0} } }; const ShapeTable *s = shape_table; @@ -867,7 +873,6 @@ void tst_QScriptEngine::kannada() { 0x0036, 0x00c1, 0x0 } }, { { 0x0cb0, 0x0ccd, 0x200d, 0x0c95, 0x0 }, { 0x0050, 0x00a7, 0x0 } }, - { {0}, {0} } }; @@ -891,6 +896,17 @@ void tst_QScriptEngine::kannada() { 0x00b0, 0x006c, 0x0 } }, { { 0x0cb7, 0x0ccd, 0x0 }, { 0x0163, 0x0 } }, + { { 0xc95, 0xcbf, 0xcd5, 0x0 }, + { 0x114, 0x73, 0x0 } }, + { { 0xc95, 0xcc6, 0xcd5, 0x0 }, + { 0x90, 0x6c, 0x73, 0x0 } }, + { { 0xc95, 0xcc6, 0xcd6, 0x0 }, + { 0x90, 0x6c, 0x74, 0x0 } }, + { { 0xc95, 0xcc6, 0xcc2, 0x0 }, + { 0x90, 0x6c, 0x69, 0x0 } }, + { { 0xc95, 0xcca, 0xcd5, 0x0 }, + { 0x90, 0x6c, 0x69, 0x73, 0x0 } }, + { {0}, {0} } }; @@ -943,7 +959,14 @@ void tst_QScriptEngine::malayalam() { 0x009e, 0x0 } }, { { 0x0d30, 0x0d4d, 0x200d, 0x0 }, { 0x009e, 0x0 } }, - + { { 0xd15, 0xd46, 0xd3e, 0x0 }, + { 0x5e, 0x34, 0x58, 0x0 } }, + { { 0xd15, 0xd47, 0xd3e, 0x0 }, + { 0x5f, 0x34, 0x58, 0x0 } }, + { { 0xd15, 0xd46, 0xd57, 0x0 }, + { 0x5e, 0x34, 0x65, 0x0 } }, + { { 0xd15, 0xd57, 0x0 }, + { 0x34, 0x65, 0x0 } }, { {0}, {0} } }; @@ -962,6 +985,39 @@ void tst_QScriptEngine::malayalam() } } +void tst_QScriptEngine::sinhala() +{ + { + FT_Face face = loadFace("FM-MalithiUW46.ttf"); + if (face) { + const ShapeTable shape_table [] = { + { { 0xd9a, 0xdd9, 0xdcf, 0x0 }, + { 0x4a, 0x61, 0x42, 0x0 } }, + { { 0xd9a, 0xdd9, 0xddf, 0x0 }, + { 0x4a, 0x61, 0x50, 0x0 } }, + { { 0xd9a, 0xdd9, 0xdca, 0x0 }, + { 0x4a, 0x62, 0x0 } }, + { { 0xd9a, 0xddc, 0xdca, 0x0 }, + { 0x4a, 0x61, 0x42, 0x41, 0x0 } }, + { { 0xd9a, 0xdda, 0x0 }, + { 0x4a, 0x62, 0x0 } }, + { { 0xd9a, 0xddd, 0x0 }, + { 0x4a, 0x61, 0x42, 0x41, 0x0 } }, + { {0}, {0} } + }; + + const ShapeTable *s = shape_table; + while (s->unicode[0]) { + QVERIFY( shaping(face, s, HB_Script_Sinhala) ); + ++s; + } + + FT_Done_Face(face); + } else { + QSKIP("couln't find FM-MalithiUW46.ttf", SkipAll); + } + } +} void tst_QScriptEngine::khmer() commit 6a5f37fba3d2db2a740dff5b0a9a2f896747b15c Author: Lars Knoll Date: Wed Nov 4 13:48:33 2009 +0100 fix a few compiler warnings and make the code more exception safe. diff --git a/src/harfbuzz-impl.c b/src/harfbuzz-impl.c index 9056a55..ddbf36b 100644 --- a/src/harfbuzz-impl.c +++ b/src/harfbuzz-impl.c @@ -33,7 +33,7 @@ HB_INTERNAL HB_Pointer _hb_alloc(size_t size, HB_Error *perror ) { - HB_Error error = 0; + HB_Error error = (HB_Error)0; HB_Pointer block = NULL; if ( size > 0 ) @@ -54,7 +54,7 @@ _hb_realloc(HB_Pointer block, HB_Error *perror ) { HB_Pointer block2 = NULL; - HB_Error error = 0; + HB_Error error = (HB_Error)0; block2 = realloc( block, new_size ); if ( block2 == NULL && new_size != 0 ) diff --git a/src/harfbuzz-shaper.cpp b/src/harfbuzz-shaper.cpp index 36b9282..f92bb55 100644 --- a/src/harfbuzz-shaper.cpp +++ b/src/harfbuzz-shaper.cpp @@ -935,7 +935,13 @@ static HB_Stream getTableStream(void *font, HB_GetFontTableFunc tableFunc, HB_Ta if (error) return 0; stream = (HB_Stream)malloc(sizeof(HB_StreamRec)); + if (!stream) + return 0; stream->base = (HB_Byte*)malloc(length); + if (!stream->base) { + free(stream); + return 0; + } error = tableFunc(font, tag, stream->base, &length); if (error) { _hb_close_stream(stream); @@ -950,6 +956,8 @@ static HB_Stream getTableStream(void *font, HB_GetFontTableFunc tableFunc, HB_Ta HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) { HB_Face face = (HB_Face )malloc(sizeof(HB_FaceRec)); + if (!face) + return 0; face->isSymbolFont = false; face->gdef = 0; @@ -961,6 +969,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) face->tmpAttributes = 0; face->tmpLogClusters = 0; face->glyphs_substituted = false; + face->buffer = 0; HB_Error error; HB_Stream stream; @@ -996,7 +1005,10 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) for (unsigned int i = 0; i < HB_ScriptCount; ++i) face->supported_scripts[i] = checkScript(face, i); - hb_buffer_new(&face->buffer); + if (hb_buffer_new(&face->buffer) != HB_Err_Ok) { + HB_FreeFace(face); + return 0; + } return face; } @@ -1116,6 +1128,8 @@ HB_Bool HB_SelectScript(HB_ShaperItem *shaper_item, const HB_OpenTypeFeature *fe HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_uint32 *properties) { + HB_GlyphAttributes *tmpAttributes; + unsigned int *tmpLogClusters; HB_Face face = item->face; @@ -1123,8 +1137,16 @@ HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_uint32 *properties) hb_buffer_clear(face->buffer); - face->tmpAttributes = (HB_GlyphAttributes *) realloc(face->tmpAttributes, face->length*sizeof(HB_GlyphAttributes)); - face->tmpLogClusters = (unsigned int *) realloc(face->tmpLogClusters, face->length*sizeof(unsigned int)); + tmpAttributes = (HB_GlyphAttributes *) realloc(face->tmpAttributes, face->length*sizeof(HB_GlyphAttributes)); + if (!tmpAttributes) + return false; + face->tmpAttributes = tmpAttributes; + + tmpLogClusters = (unsigned int *) realloc(face->tmpLogClusters, face->length*sizeof(unsigned int)); + if (!tmpLogClusters) + return false; + face->tmpLogClusters = tmpLogClusters; + for (int i = 0; i < face->length; ++i) { hb_buffer_add_glyph(face->buffer, item->glyphs[i], properties ? properties[i] : 0, i); face->tmpAttributes[i] = item->attributes[i]; diff --git a/src/harfbuzz-stream.c b/src/harfbuzz-stream.c index 3dcee82..2d9638f 100644 --- a/src/harfbuzz-stream.c +++ b/src/harfbuzz-stream.c @@ -70,7 +70,7 @@ HB_INTERNAL HB_Error _hb_stream_seek( HB_Stream stream, HB_UInt pos ) { - HB_Error error = 0; + HB_Error error = (HB_Error)0; stream->pos = pos; if (pos > stream->size) From agl at google.com Fri Nov 6 07:14:27 2009 From: agl at google.com (Adam Langley) Date: Fri, 6 Nov 2009 07:14:27 -0800 Subject: [HarfBuzz] not linking to libstdc++ In-Reply-To: <20091106144657.217724f3@sil-mh5.dallas.sil.org> References: <20091106144657.217724f3@sil-mh5.dallas.sil.org> Message-ID: On Thu, Nov 5, 2009 at 11:46 PM, Martin Hosken wrote: > I'm about to try adding graphite support as a contrib to harfbuzz-ng. Graphite itself is in C++ and so the linking code is going to have to bridge between C and C++. But I notice that you go to great lengths to ensure that harfbuzz doesn't link to libstdc++. I am wondering why this is the case. Harfbuzz is a C library. It would be very sad if it needed to pull in libstdc++. That would pollute Pango, and then the rest of the GNOME/GTK world. AGL From behdad at behdad.org Fri Nov 6 10:46:48 2009 From: behdad at behdad.org (Behdad Esfahbod) Date: Fri, 06 Nov 2009 13:46:48 -0500 Subject: [HarfBuzz] not linking to libstdc++ In-Reply-To: <20091106144657.217724f3@sil-mh5.dallas.sil.org> References: <20091106144657.217724f3@sil-mh5.dallas.sil.org> Message-ID: <4AF46F18.6020101@behdad.org> On 11/06/2009 02:46 AM, Martin Hosken wrote: > Dear Behdad, > > I'm about to try adding graphite support as a contrib to harfbuzz-ng. Graphite itself is in C++ and so the linking code is going to have to bridge between C and C++. But I notice that you go to great lengths to ensure that harfbuzz doesn't link to libstdc++. I am wondering why this is the case. Hi Martin, Basically what Adam already said: We don't want an unused libstdc++ dependency for GNOME. That said, I need to figure out how to compile/link all the various backends and glue code. Right now I have glue code for glib, FreeType, and ICU, and all are compiled into libharfbuzz.so. Linking to ICU is also a problem for GNOME (at least right now). So what I probably end up doing is to either: 1) Move ICU code in libharfbuzz-icu.so. Kind of an overkill since that library will expose one and only one function. 2) Use dlopen so we can avoid linking to ICU. The same can't be said about Graphite though since being a backend, we need to access it even if the user doesn't ask for it. Having modules like Pango has may help here. Again, this is something I have not figured out yet, but expect to figure out by winter time (which is about freeze time for GNOME). In the mean time, the goal is to get all the code we need ported to this framework so we can call the API stable with some confidence. So, thanks for looking into it. Cheers, behdad > TIA, > Yours, > Martin From behdad at kemper.freedesktop.org Fri Nov 6 10:54:01 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 6 Nov 2009 10:54:01 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' Message-ID: <20091106185401.5995310051@kemper.freedesktop.org> src/hb-shape.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) New commits: commit 1ff7775051559a8ca442be3938450c7ed3817806 Author: Behdad Esfahbod Date: Fri Nov 6 13:52:57 2009 -0500 Minor. diff --git a/src/hb-shape.c b/src/hb-shape.c index fa5b362..130bcc4 100644 --- a/src/hb-shape.c +++ b/src/hb-shape.c @@ -90,9 +90,13 @@ hb_shape (hb_font_t *font, /* OT preprocess */ hb_map_glyphs (font, face, buffer); + /* ccmp+... */ + + /* script-specific */ /* GSUB */ + hb_position_default (font, face, buffer); - /* Default positioning */ + /* GPOS / kern */ } From behdad at behdad.org Fri Nov 6 11:02:51 2009 From: behdad at behdad.org (Behdad Esfahbod) Date: Fri, 06 Nov 2009 14:02:51 -0500 Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' In-Reply-To: <20091106185401.5995310051@kemper.freedesktop.org> References: <20091106185401.5995310051@kemper.freedesktop.org> Message-ID: <4AF472DB.9050306@behdad.org> Ok, so I hooked harfbuzz-ng post-commit to send diffs to the list. behdad On 11/06/2009 01:54 PM, Behdad Esfahbod wrote: > src/hb-shape.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > New commits: > commit 1ff7775051559a8ca442be3938450c7ed3817806 > Author: Behdad Esfahbod > Date: Fri Nov 6 13:52:57 2009 -0500 > > Minor. > > diff --git a/src/hb-shape.c b/src/hb-shape.c > index fa5b362..130bcc4 100644 > --- a/src/hb-shape.c > +++ b/src/hb-shape.c > @@ -90,9 +90,13 @@ hb_shape (hb_font_t *font, > /* OT preprocess */ > > hb_map_glyphs (font, face, buffer); > + /* ccmp+... */ > + > + /* script-specific */ > > /* GSUB */ > + > hb_position_default (font, face, buffer); > - /* Default positioning */ > + > /* GPOS / kern */ > } > _______________________________________________ > HarfBuzz mailing list > HarfBuzz at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/harfbuzz > From behdad at kemper.freedesktop.org Fri Nov 6 13:49:16 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 6 Nov 2009 13:49:16 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' - 3 commits Message-ID: <20091106214918.3966410051@kemper.freedesktop.org> src/hb-buffer-private.h | 6 ---- src/hb-buffer.c | 2 - src/hb-buffer.h | 13 +-------- src/hb-ft.c | 2 - src/hb-ot-layout-gpos-private.hh | 8 +++--- src/hb-ot-layout.cc | 52 +++++++++++++++++++++++++++++++++++++++ src/hb-ot-layout.h | 16 ++++++++---- 7 files changed, 72 insertions(+), 27 deletions(-) New commits: commit 9db8ad75317d589807e7725455f49cafece58d5d Author: Behdad Esfahbod Date: Fri Nov 6 16:47:31 2009 -0500 Add hb_ot_layout_position_finish() We expect buffer to be setup with default positions before GPOS. diff --git a/src/hb-buffer-private.h b/src/hb-buffer-private.h index f98f768..3a74f2e 100644 --- a/src/hb-buffer-private.h +++ b/src/hb-buffer-private.h @@ -51,11 +51,7 @@ typedef struct _hb_internal_glyph_position_t { hb_position_t y_advance; hb_position_t x_offset; hb_position_t y_offset; - uint32_t new_advance :1; /* if set, the advance width values are - absolute, i.e., they won't be - added to the original glyph's value - but rather replace them */ - uint32_t back : 15; /* number of glyphs to go back + uint32_t back : 16; /* number of glyphs to go back for drawing current glyph */ int32_t cursive_chain : 16; /* character to which this connects, may be positive or negative; used diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 195ad34..fb87220 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -56,16 +56,7 @@ typedef struct _hb_glyph_position_t { hb_position_t y_advance; hb_position_t x_offset; hb_position_t y_offset; - /* XXX these should all be replaced by "uint32_t internal" */ - uint32_t new_advance :1; /* if set, the advance width values are - absolute, i.e., they won't be - added to the original glyph's value - but rather replace them */ - uint32_t back : 15; /* number of glyphs to go back - for drawing current glyph */ - int32_t cursive_chain : 16; /* character to which this connects, - may be positive or negative; used - only internally */ + uint32_t internal; } hb_glyph_position_t; diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh index 3159ab1..f8cbe78 100644 --- a/src/hb-ot-layout-gpos-private.hh +++ b/src/hb-ot-layout-gpos-private.hh @@ -840,13 +840,13 @@ struct CursivePosFormat1 if (buffer->direction == HB_DIRECTION_RTL) { - POSITION (buffer->in_pos)->x_advance = entry_x - gpi->anchor_x; - POSITION (buffer->in_pos)->new_advance = true; + /* advance is absolute, not relative */ + POSITION (buffer->in_pos)->x_advance = entry_x - gpi->anchor_x; } else { - POSITION (last_pos)->x_advance = gpi->anchor_x - entry_x; - POSITION (last_pos)->new_advance = true; + /* advance is absolute, not relative */ + POSITION (last_pos)->x_advance = gpi->anchor_x - entry_x; } if (lookup_flag & LookupFlag::RightToLeft) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index d48ef70..45ace5b 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -564,3 +564,55 @@ hb_ot_layout_position_lookup (hb_face_t *face, context.face = face; return _get_gpos (face).position_lookup (&context, buffer, lookup_index, mask); } + +#include +void +hb_ot_layout_position_finish (hb_face_t *face, + hb_font_t *font, + hb_buffer_t *buffer) +{ + unsigned int i, j; + unsigned int len = hb_buffer_get_length (buffer); + hb_internal_glyph_position_t *positions = (hb_internal_glyph_position_t *) hb_buffer_get_glyph_positions (buffer); + + /* TODO: Vertical */ + + /* Handle cursive connections */ + /* First handle all left-to-right connections */ + for (j = 0; j < len; j++) { + if (positions[j].cursive_chain > 0) { + printf ("0000000000000\n"); + positions[j].y_offset += positions[j - positions[j].cursive_chain].y_offset; + positions[j].cursive_chain = 0; + } + } + /* Then handle all right-to-left connections */ + for (i = len; i > 0; i--) { + j = i - 1; + if (positions[j].cursive_chain < 0) { + positions[j].y_offset += positions[j - positions[j].cursive_chain].y_offset; + positions[j].cursive_chain = 0; + } + } + + /* Handle attachments */ + for (i = 0; i < len; i++) + if (positions[i].back) + { + unsigned int back = i - positions[i].back; + positions[i].back = 0; + positions[i].x_offset += positions[back].x_offset; + positions[i].y_offset += positions[back].y_offset; + + if (buffer->direction == HB_DIRECTION_RTL) + for (j = back + 1; j < i + 1; j++) { + positions[i].x_offset += positions[j].x_advance; + positions[i].y_offset += positions[j].y_advance; + } + else + for (j = back; j < i; j++) { + positions[i].x_offset -= positions[j].x_advance; + positions[i].y_offset -= positions[j].y_advance; + } + } +} diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 773828e..40ead82 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -198,11 +198,17 @@ hb_bool_t hb_ot_layout_has_positioning (hb_face_t *face); hb_bool_t -hb_ot_layout_position_lookup (hb_face_t *face, - hb_font_t *font, - hb_buffer_t *buffer, - unsigned int lookup_index, - hb_mask_t mask); +hb_ot_layout_position_lookup (hb_face_t *face, + hb_font_t *font, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_mask_t mask); + +/* Should be called after all the position_lookup's are done */ +void +hb_ot_layout_position_finish (hb_face_t *face, + hb_font_t *font, + hb_buffer_t *buffer); HB_END_DECLS commit edb54e9aeca25f4120a69ed3d5562cbb68fdb348 Author: Behdad Esfahbod Date: Fri Nov 6 15:19:22 2009 -0500 Fix FT_Face finalizer call diff --git a/src/hb-ft.c b/src/hb-ft.c index 83eb2db..e8295cf 100644 --- a/src/hb-ft.c +++ b/src/hb-ft.c @@ -192,7 +192,7 @@ hb_ft_face_create_cached (FT_Face ft_face) if (HB_UNLIKELY (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize)) { if (ft_face->generic.finalizer) - ft_face->generic.finalizer (ft_face->generic.data); + ft_face->generic.finalizer (ft_face); ft_face->generic.data = hb_ft_face_create (ft_face, NULL); ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize; commit 3d14528b8b2e7da425a9df7057fc9fb326d8298c Author: Behdad Esfahbod Date: Fri Nov 6 15:13:17 2009 -0500 Rename hb_buffer_get_len() to hb_buffer_get_length() diff --git a/src/hb-buffer.c b/src/hb-buffer.c index d70a6cd..1e4867d 100644 --- a/src/hb-buffer.c +++ b/src/hb-buffer.c @@ -413,7 +413,7 @@ _hb_buffer_allocate_lig_id (hb_buffer_t *buffer) unsigned int -hb_buffer_get_len (hb_buffer_t *buffer) +hb_buffer_get_length (hb_buffer_t *buffer) { return buffer->in_length; } diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 5c9d408..195ad34 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -159,7 +159,7 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, /* Return value valid as long as buffer not modified */ unsigned int -hb_buffer_get_len (hb_buffer_t *buffer); +hb_buffer_get_length (hb_buffer_t *buffer); /* Return value valid as long as buffer not modified */ hb_glyph_info_t * From behdad at kemper.freedesktop.org Fri Nov 6 14:22:18 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 6 Nov 2009 14:22:18 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' Message-ID: <20091106222224.F07AB10051@kemper.freedesktop.org> src/hb-buffer-private.h | 10 +++++++- src/hb-buffer.c | 45 +++++++++++++++++++++++++++++++++++++-- src/hb-ot-layout-gsub-private.hh | 16 ++++++------- 3 files changed, 60 insertions(+), 11 deletions(-) New commits: commit 25e7ef704633447f109b148620336c42d6fb310e Author: Behdad Esfahbod Date: Fri Nov 6 17:21:01 2009 -0500 Add _hb_buffer_add_output_glyphs() that takes codepoint_t* diff --git a/src/hb-buffer-private.h b/src/hb-buffer-private.h index 3a74f2e..dab403b 100644 --- a/src/hb-buffer-private.h +++ b/src/hb-buffer-private.h @@ -102,11 +102,19 @@ HB_INTERNAL void _hb_buffer_add_output_glyphs (hb_buffer_t *buffer, unsigned int num_in, unsigned int num_out, - const uint16_t *glyph_data_be, + const hb_codepoint_t *glyph_data, unsigned short component, unsigned short ligID); HB_INTERNAL void +_hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer, + unsigned int num_in, + unsigned int num_out, + const uint16_t *glyph_data_be, + unsigned short component, + unsigned short ligID); + +HB_INTERNAL void _hb_buffer_add_output_glyph (hb_buffer_t *buffer, hb_codepoint_t glyph_index, unsigned short component, diff --git a/src/hb-buffer.c b/src/hb-buffer.c index 1e4867d..76b69c8 100644 --- a/src/hb-buffer.c +++ b/src/hb-buffer.c @@ -305,11 +305,12 @@ _hb_buffer_swap (hb_buffer_t *buffer) The cluster value for the glyph at position buffer->in_pos is used for all replacement glyphs */ + void _hb_buffer_add_output_glyphs (hb_buffer_t *buffer, unsigned int num_in, unsigned int num_out, - const uint16_t *glyph_data_be, + const hb_codepoint_t *glyph_data, unsigned short component, unsigned short lig_id) { @@ -333,7 +334,7 @@ _hb_buffer_add_output_glyphs (hb_buffer_t *buffer, for (i = 0; i < num_out; i++) { hb_internal_glyph_info_t *info = &buffer->out_string[buffer->out_pos + i]; - info->codepoint = hb_be_uint16 (glyph_data_be[i]); + info->codepoint = glyph_data[i]; info->mask = mask; info->cluster = cluster; info->component = component; @@ -346,6 +347,46 @@ _hb_buffer_add_output_glyphs (hb_buffer_t *buffer, buffer->out_length = buffer->out_pos; } +void +_hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer, + unsigned int num_in, + unsigned int num_out, + const uint16_t *glyph_data_be, + unsigned short component, + unsigned short lig_id) +{ + unsigned int i; + unsigned int mask; + unsigned int cluster; + + if (buffer->out_string != buffer->in_string || + buffer->out_pos + num_out > buffer->in_pos + num_in) + { + hb_buffer_ensure_separate (buffer, buffer->out_pos + num_out); + } + + mask = buffer->in_string[buffer->in_pos].mask; + cluster = buffer->in_string[buffer->in_pos].cluster; + if (component == 0xFFFF) + component = buffer->in_string[buffer->in_pos].component; + if (lig_id == 0xFFFF) + lig_id = buffer->in_string[buffer->in_pos].lig_id; + + for (i = 0; i < num_out; i++) + { + hb_internal_glyph_info_t *info = &buffer->out_string[buffer->out_pos + i]; + info->codepoint = hb_be_uint16 (glyph_data_be[i]); + info->mask = mask; + info->cluster = cluster; + info->component = component; + info->lig_id = lig_id; + info->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN; + } + + buffer->in_pos += num_in; + buffer->out_pos += num_out; + buffer->out_length = buffer->out_pos; +} void _hb_buffer_add_output_glyph (hb_buffer_t *buffer, diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh index eb74c03..fd161c0 100644 --- a/src/hb-ot-layout-gsub-private.hh +++ b/src/hb-ot-layout-gsub-private.hh @@ -158,9 +158,9 @@ struct Sequence if (HB_UNLIKELY (!substitute.len)) return false; - _hb_buffer_add_output_glyphs (buffer, 1, - substitute.len, (const uint16_t *) substitute.const_array(), - 0xFFFF, 0xFFFF); + _hb_buffer_add_output_glyphs_be16 (buffer, 1, + substitute.len, (const uint16_t *) substitute.const_array(), + 0xFFFF, 0xFFFF); /* This is a guess only ... */ if (_hb_ot_layout_has_new_glyph_classes (context->face)) @@ -386,11 +386,11 @@ struct Ligature if (j == buffer->in_pos + i) /* No input glyphs skipped */ /* We don't use a new ligature ID if there are no skipped glyphs and the ligature already has an ID. */ - _hb_buffer_add_output_glyphs (buffer, i, - 1, (const uint16_t *) &ligGlyph, - 0xFFFF, - IN_LIGID (buffer->in_pos) ? - 0xFFFF : _hb_buffer_allocate_lig_id (buffer)); + _hb_buffer_add_output_glyphs_be16 (buffer, i, + 1, (const uint16_t *) &ligGlyph, + 0xFFFF, + IN_LIGID (buffer->in_pos) ? + 0xFFFF : _hb_buffer_allocate_lig_id (buffer)); else { unsigned int lig_id = _hb_buffer_allocate_lig_id (buffer); From behdad at kemper.freedesktop.org Fri Nov 6 14:25:19 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 6 Nov 2009 14:25:19 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' Message-ID: <20091106222520.0B15610051@kemper.freedesktop.org> src/hb-ot-layout-gsub-private.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) New commits: commit aa196d6026b496ec70be3d3588cc8cd2b8ccdb36 Author: Behdad Esfahbod Date: Fri Nov 6 17:23:31 2009 -0500 [GSUB] More ligature/component fixing We can only reuse the ligid if it belongs to a previous ligature, not a component! diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh index fd161c0..d0cec7b 100644 --- a/src/hb-ot-layout-gsub-private.hh +++ b/src/hb-ot-layout-gsub-private.hh @@ -388,8 +388,8 @@ struct Ligature glyphs and the ligature already has an ID. */ _hb_buffer_add_output_glyphs_be16 (buffer, i, 1, (const uint16_t *) &ligGlyph, - 0xFFFF, - IN_LIGID (buffer->in_pos) ? + 0, + IN_LIGID (buffer->in_pos) && !IN_COMPONENT (buffer->in_pos) ? 0xFFFF : _hb_buffer_allocate_lig_id (buffer)); else { From behdad at kemper.freedesktop.org Fri Nov 6 14:43:47 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 6 Nov 2009 14:43:47 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' Message-ID: <20091106224347.8ECE710051@kemper.freedesktop.org> src/hb-ot-layout.cc | 2 -- 1 file changed, 2 deletions(-) New commits: commit f4f1fc970b3e37d9903cbf5e05bbd38be4df3047 Author: Behdad Esfahbod Date: Fri Nov 6 17:42:38 2009 -0500 Remove debug info that crept in diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 45ace5b..0c2f602 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -565,7 +565,6 @@ hb_ot_layout_position_lookup (hb_face_t *face, return _get_gpos (face).position_lookup (&context, buffer, lookup_index, mask); } -#include void hb_ot_layout_position_finish (hb_face_t *face, hb_font_t *font, @@ -581,7 +580,6 @@ hb_ot_layout_position_finish (hb_face_t *face, /* First handle all left-to-right connections */ for (j = 0; j < len; j++) { if (positions[j].cursive_chain > 0) { - printf ("0000000000000\n"); positions[j].y_offset += positions[j - positions[j].cursive_chain].y_offset; positions[j].cursive_chain = 0; } From behdad at kemper.freedesktop.org Fri Nov 6 14:46:51 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 6 Nov 2009 14:46:51 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' Message-ID: <20091106224651.BA6ED10051@kemper.freedesktop.org> src/hb-ot-layout.cc | 14 +++++++------- src/hb-ot-layout.h | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) New commits: commit 52ea47767c7c35650ebddfba6ddc8203a3e33d3a Author: Behdad Esfahbod Date: Fri Nov 6 17:45:38 2009 -0500 Change order of font and face for API consistency diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 0c2f602..5e51800 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -96,7 +96,7 @@ _get_gpos (hb_face_t *face) /* TODO the public class_t is a mess */ hb_bool_t -hb_ot_layout_has_font_glyph_classes (hb_face_t *face) +hb_ot_layout_has_glyph_classes (hb_face_t *face) { return _get_gdef (face).has_glyph_classes (); } @@ -312,8 +312,8 @@ hb_ot_layout_get_attach_points (hb_face_t *face, } unsigned int -hb_ot_layout_get_lig_carets (hb_face_t *face, - hb_font_t *font, +hb_ot_layout_get_lig_carets (hb_font_t *font, + hb_face_t *face, hb_codepoint_t glyph, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, @@ -553,8 +553,8 @@ hb_ot_layout_has_positioning (hb_face_t *face) } hb_bool_t -hb_ot_layout_position_lookup (hb_face_t *face, - hb_font_t *font, +hb_ot_layout_position_lookup (hb_font_t *font, + hb_face_t *face, hb_buffer_t *buffer, unsigned int lookup_index, hb_mask_t mask) @@ -566,8 +566,8 @@ hb_ot_layout_position_lookup (hb_face_t *face, } void -hb_ot_layout_position_finish (hb_face_t *face, - hb_font_t *font, +hb_ot_layout_position_finish (hb_font_t *font, + hb_face_t *face, hb_buffer_t *buffer) { unsigned int i, j; diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 40ead82..ee7bc85 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -55,7 +55,7 @@ typedef enum { * classes in harfbuzz. */ hb_bool_t -hb_ot_layout_has_font_glyph_classes (hb_face_t *face); +hb_ot_layout_glyph_classes (hb_face_t *face); hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_face_t *face, @@ -84,8 +84,8 @@ hb_ot_layout_get_attach_points (hb_face_t *face, /* Ligature caret positions */ unsigned int -hb_ot_layout_get_lig_carets (hb_face_t *face, - hb_font_t *font, +hb_ot_layout_get_lig_carets (hb_font_t *font, + hb_face_t *face, hb_codepoint_t glyph, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, @@ -198,16 +198,16 @@ hb_bool_t hb_ot_layout_has_positioning (hb_face_t *face); hb_bool_t -hb_ot_layout_position_lookup (hb_face_t *face, - hb_font_t *font, +hb_ot_layout_position_lookup (hb_font_t *font, + hb_face_t *face, hb_buffer_t *buffer, unsigned int lookup_index, hb_mask_t mask); /* Should be called after all the position_lookup's are done */ void -hb_ot_layout_position_finish (hb_face_t *face, - hb_font_t *font, +hb_ot_layout_position_finish (hb_font_t *font, + hb_face_t *face, hb_buffer_t *buffer); From behdad at kemper.freedesktop.org Fri Nov 6 14:47:39 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 6 Nov 2009 14:47:39 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' Message-ID: <20091106224740.25F1510051@kemper.freedesktop.org> src/hb-ot-layout.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit b4b4272c8d19ba3e0cb8f12b3b7d1590349e3d14 Author: Behdad Esfahbod Date: Fri Nov 6 17:46:33 2009 -0500 Oops, wrong change diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index ee7bc85..2935254 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -55,7 +55,7 @@ typedef enum { * classes in harfbuzz. */ hb_bool_t -hb_ot_layout_glyph_classes (hb_face_t *face); +hb_ot_layout_has_glyph_classes (hb_face_t *face); hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_face_t *face, From behdad at kemper.freedesktop.org Fri Nov 6 16:53:55 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 6 Nov 2009 16:53:55 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' - 3 commits Message-ID: <20091107005356.1385610051@kemper.freedesktop.org> src/hb-buffer-private.h | 1 src/hb-buffer.c | 42 +++++++++++++++++-- src/hb-buffer.h | 10 +--- src/hb-common.h | 11 +++++ src/hb-shape.c | 43 +++++++++++++++++-- src/hb-unicode-private.h | 5 ++ src/hb-unicode.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 200 insertions(+), 15 deletions(-) New commits: commit bf2b25dd8591e92f3944c763641b613a70c379a7 Author: Behdad Esfahbod Date: Fri Nov 6 19:52:47 2009 -0500 Remove done item diff --git a/src/hb-shape.c b/src/hb-shape.c index ccc1021..c5e9d47 100644 --- a/src/hb-shape.c +++ b/src/hb-shape.c @@ -116,7 +116,6 @@ hb_shape (hb_font_t *font, original_direction = hb_ensure_native_direction (buffer); /* do_mirroring (buffer); */ - /* natural direction analysis */ /* OT preprocess */ hb_map_glyphs (font, face, buffer); commit 4a8605315901e0ff1e6e09437a92dd5ac39164cc Author: Behdad Esfahbod Date: Fri Nov 6 19:52:01 2009 -0500 Reverse buffer at the end if RTL diff --git a/src/hb-shape.c b/src/hb-shape.c index 01fce83..ccc1021 100644 --- a/src/hb-shape.c +++ b/src/hb-shape.c @@ -89,14 +89,14 @@ hb_position_default (hb_font_t *font, static hb_direction_t hb_ensure_native_direction (hb_buffer_t *buffer) { - hb_direction_t original_direction = hb_buffer_get_direction (buffer); + hb_direction_t original_direction = buffer->direction; /* TODO vertical */ if (HB_DIRECTION_IS_HORIZONTAL (original_direction) && - original_direction != _hb_script_get_horizontal_direction (hb_buffer_get_script (buffer))) + original_direction != _hb_script_get_horizontal_direction (buffer->script)) { hb_buffer_reverse_clusters (buffer); - hb_buffer_set_direction (buffer, original_direction == HB_DIRECTION_LTR ? HB_DIRECTION_RTL : HB_DIRECTION_LTR); + buffer->direction ^= 1; } return original_direction; @@ -130,5 +130,9 @@ hb_shape (hb_font_t *font, /* GPOS / kern */ - hb_buffer_set_direction (buffer, original_direction); + /* TODO: Vertical */ + if (buffer->direction == HB_DIRECTION_RTL) + hb_buffer_reverse (buffer); + + buffer->direction = original_direction; } commit ff44f88df2c46920f3ec2384ef321a4c7bb0f6ef Author: Behdad Esfahbod Date: Fri Nov 6 19:48:16 2009 -0500 Handle shaping in non-native direction diff --git a/src/hb-buffer-private.h b/src/hb-buffer-private.h index dab403b..6ba1a21 100644 --- a/src/hb-buffer-private.h +++ b/src/hb-buffer-private.h @@ -138,6 +138,7 @@ _hb_buffer_allocate_lig_id (hb_buffer_t *buffer); #define IN_NEXTGLYPH() (buffer->in_string[buffer->in_pos + 1].codepoint) #define IN_CURINFO() (&buffer->in_string[buffer->in_pos]) #define IN_MASK(pos) (buffer->in_string[(pos)].mask) +#define IN_CLUSTER(pos) (buffer->in_string[(pos)].cluster) #define IN_LIGID(pos) (buffer->in_string[(pos)].lig_id) #define IN_COMPONENT(pos) (buffer->in_string[(pos)].component) #define POSITION(pos) (&buffer->positions[(pos)]) diff --git a/src/hb-buffer.c b/src/hb-buffer.c index 76b69c8..723b8bd 100644 --- a/src/hb-buffer.c +++ b/src/hb-buffer.c @@ -477,12 +477,14 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer) } -void -hb_buffer_reverse (hb_buffer_t *buffer) +static void +reverse_range (hb_buffer_t *buffer, + unsigned int start, + unsigned int end) { unsigned int i, j; - for (i = 0, j = buffer->in_length - 1; i < buffer->in_length / 2; i++, j--) { + for (i = start, j = end - 1; i < j; i++, j--) { hb_internal_glyph_info_t t; t = buffer->in_string[i]; @@ -491,7 +493,7 @@ hb_buffer_reverse (hb_buffer_t *buffer) } if (buffer->positions) { - for (i = 0, j = buffer->in_length - 1; i < buffer->in_length / 2; i++, j--) { + for (i = 0, j = end - 1; i < j; i++, j--) { hb_internal_glyph_position_t t; t = buffer->positions[i]; @@ -501,6 +503,38 @@ hb_buffer_reverse (hb_buffer_t *buffer) } } +void +hb_buffer_reverse (hb_buffer_t *buffer) +{ + if (HB_UNLIKELY (!buffer->in_length)) + return; + + reverse_range (buffer, 0, buffer->in_length); +} + +void +hb_buffer_reverse_clusters (hb_buffer_t *buffer) +{ + unsigned int i, start, count, last_cluster; + + if (HB_UNLIKELY (!buffer->in_length)) + return; + + hb_buffer_reverse (buffer); + + count = buffer->in_length; + start = 0; + last_cluster = buffer->in_string[0].cluster; + for (i = 1; i < count; i++) { + if (last_cluster != buffer->in_string[i].cluster) { + reverse_range (buffer, start, i); + start = i; + last_cluster = buffer->in_string[i].cluster; + } + } + reverse_range (buffer, start, i); +} + #define ADD_UTF(T) \ HB_STMT_START { \ diff --git a/src/hb-buffer.h b/src/hb-buffer.h index fb87220..0bceada 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -36,13 +36,6 @@ HB_BEGIN_DECLS typedef struct _hb_buffer_t hb_buffer_t; -typedef enum _hb_direction_t { - HB_DIRECTION_LTR, - HB_DIRECTION_RTL, - HB_DIRECTION_TTB, - HB_DIRECTION_BTT -} hb_direction_t; - typedef struct _hb_glyph_info_t { hb_codepoint_t codepoint; hb_mask_t mask; @@ -115,6 +108,9 @@ hb_buffer_ensure (hb_buffer_t *buffer, void hb_buffer_reverse (hb_buffer_t *buffer); +void +hb_buffer_reverse_clusters (hb_buffer_t *buffer); + /* Filling the buffer in */ diff --git a/src/hb-common.h b/src/hb-common.h index 863d412..d07b204 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -72,4 +72,15 @@ typedef uint32_t hb_mask_t; typedef void (*hb_destroy_func_t) (void *user_data); +typedef enum _hb_direction_t { + HB_DIRECTION_LTR, + HB_DIRECTION_RTL, + HB_DIRECTION_TTB, + HB_DIRECTION_BTT +} hb_direction_t; + +#define HB_DIRECTION_IS_HORIZONTAL(dir) ((dir) == HB_DIRECTION_LTR || (dir) == HB_DIRECTION_RTL) +#define HB_DIRECTION_IS_VERTICAL(dir) ((dir) == HB_DIRECTION_TTB || (dir) == HB_DIRECTION_BTT) + + #endif /* HB_COMMON_H */ diff --git a/src/hb-shape.c b/src/hb-shape.c index 130bcc4..01fce83 100644 --- a/src/hb-shape.c +++ b/src/hb-shape.c @@ -38,6 +38,17 @@ is_variation_selector (hb_codepoint_t unicode) } static void +hb_form_clusters (hb_buffer_t *buffer) +{ + unsigned int count; + + count = buffer->in_length; + for (buffer->in_pos = 1; buffer->in_pos < count; buffer->in_pos++) + if (buffer->unicode->get_general_category (IN_CURGLYPH()) == HB_CATEGORY_NON_SPACING_MARK) + IN_CLUSTER (buffer->in_pos) = IN_CLUSTER (buffer->in_pos - 1); +} + +static void hb_map_glyphs (hb_font_t *font, hb_face_t *face, hb_buffer_t *buffer) @@ -45,7 +56,6 @@ hb_map_glyphs (hb_font_t *font, unsigned int count; count = buffer->in_length - 1; - for (buffer->in_pos = 0; buffer->in_pos < count; buffer->in_pos++) { if (HB_UNLIKELY (is_variation_selector (IN_NEXTGLYPH()))) { IN_CURGLYPH() = hb_font_get_glyph (font, face, IN_CURGLYPH(), IN_NEXTGLYPH()); @@ -67,7 +77,6 @@ hb_position_default (hb_font_t *font, hb_buffer_clear_positions (buffer); count = buffer->in_length; - for (buffer->in_pos = 0; buffer->in_pos < count; buffer->in_pos++) { hb_glyph_metrics_t metrics; hb_font_get_glyph_metrics (font, face, IN_CURGLYPH(), &metrics); @@ -77,6 +86,23 @@ hb_position_default (hb_font_t *font, } +static hb_direction_t +hb_ensure_native_direction (hb_buffer_t *buffer) +{ + hb_direction_t original_direction = hb_buffer_get_direction (buffer); + + /* TODO vertical */ + if (HB_DIRECTION_IS_HORIZONTAL (original_direction) && + original_direction != _hb_script_get_horizontal_direction (hb_buffer_get_script (buffer))) + { + hb_buffer_reverse_clusters (buffer); + hb_buffer_set_direction (buffer, original_direction == HB_DIRECTION_LTR ? HB_DIRECTION_RTL : HB_DIRECTION_LTR); + } + + return original_direction; +} + + void hb_shape (hb_font_t *font, hb_face_t *face, @@ -84,7 +110,11 @@ hb_shape (hb_font_t *font, hb_feature_t *features, unsigned int num_features) { - /* form_clusters (buffer); */ + hb_direction_t original_direction; + + hb_form_clusters (buffer); + original_direction = hb_ensure_native_direction (buffer); + /* do_mirroring (buffer); */ /* natural direction analysis */ /* OT preprocess */ @@ -99,4 +129,6 @@ hb_shape (hb_font_t *font, hb_position_default (font, face, buffer); /* GPOS / kern */ + + hb_buffer_set_direction (buffer, original_direction); } diff --git a/src/hb-unicode-private.h b/src/hb-unicode-private.h index 8880245..1a970b4 100644 --- a/src/hb-unicode-private.h +++ b/src/hb-unicode-private.h @@ -52,6 +52,11 @@ struct _hb_unicode_funcs_t { HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_nil; + +HB_INTERNAL hb_direction_t +_hb_script_get_horizontal_direction (hb_script_t script); + + HB_END_DECLS #endif /* HB_UNICODE_PRIVATE_H */ diff --git a/src/hb-unicode.c b/src/hb-unicode.c index 01b54f5..d8ea0ea 100644 --- a/src/hb-unicode.c +++ b/src/hb-unicode.c @@ -159,3 +159,106 @@ hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, ufuncs->get_eastasian_width = eastasian_width_func ? eastasian_width_func : hb_unicode_get_eastasian_width_nil; } + +#define LTR HB_DIRECTION_LTR +#define RTL HB_DIRECTION_RTL +const hb_direction_t horiz_dir[] = +{ + LTR, /* Zyyy */ + LTR, /* Qaai */ + RTL, /* Arab */ + LTR, /* Armn */ + LTR, /* Beng */ + LTR, /* Bopo */ + LTR, /* Cher */ + LTR, /* Qaac */ + LTR, /* Cyrl (Cyrs) */ + LTR, /* Dsrt */ + LTR, /* Deva */ + LTR, /* Ethi */ + LTR, /* Geor (Geon, Geoa) */ + LTR, /* Goth */ + LTR, /* Grek */ + LTR, /* Gujr */ + LTR, /* Guru */ + LTR, /* Hani */ + LTR, /* Hang */ + RTL, /* Hebr */ + LTR, /* Hira */ + LTR, /* Knda */ + LTR, /* Kana */ + LTR, /* Khmr */ + LTR, /* Laoo */ + LTR, /* Latn (Latf, Latg) */ + LTR, /* Mlym */ + LTR, /* Mong */ + LTR, /* Mymr */ + LTR, /* Ogam */ + LTR, /* Ital */ + LTR, /* Orya */ + LTR, /* Runr */ + LTR, /* Sinh */ + RTL, /* Syrc (Syrj, Syrn, Syre) */ + LTR, /* Taml */ + LTR, /* Telu */ + RTL, /* Thaa */ + LTR, /* Thai */ + LTR, /* Tibt */ + LTR, /* Cans */ + LTR, /* Yiii */ + LTR, /* Tglg */ + LTR, /* Hano */ + LTR, /* Buhd */ + LTR, /* Tagb */ + + /* Unicode-4.0 additions */ + LTR, /* Brai */ + LTR, /* Cprt */ + LTR, /* Limb */ + LTR, /* Osma */ + LTR, /* Shaw */ + LTR, /* Linb */ + LTR, /* Tale */ + LTR, /* Ugar */ + + /* Unicode-4.1 additions */ + LTR, /* Talu */ + LTR, /* Bugi */ + LTR, /* Glag */ + LTR, /* Tfng */ + LTR, /* Sylo */ + LTR, /* Xpeo */ + LTR, /* Khar */ + + /* Unicode-5.0 additions */ + LTR, /* Zzzz */ + LTR, /* Bali */ + LTR, /* Xsux */ + RTL, /* Phnx */ + LTR, /* Phag */ + RTL, /* Nkoo */ + + /* Unicode-5.1 additions */ + LTR, /* Kali */ + LTR, /* Lepc */ + LTR, /* Rjng */ + LTR, /* Sund */ + LTR, /* Saur */ + LTR, /* Cham */ + LTR, /* Olck */ + LTR, /* Vaii */ + LTR, /* Cari */ + LTR, /* Lyci */ + LTR /* Lydi */ +}; +#undef LTR +#undef RTL + +HB_INTERNAL hb_direction_t +_hb_script_get_horizontal_direction (hb_script_t script) +{ + if (HB_UNLIKELY ((unsigned int) script >= ARRAY_LENGTH (horiz_dir))) + return HB_DIRECTION_LTR; + + return horiz_dir[script]; +} From behdad at kemper.freedesktop.org Wed Nov 11 14:16:20 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Wed, 11 Nov 2009 14:16:20 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' - 2 commits Message-ID: <20091111221620.35A4E10051@kemper.freedesktop.org> src/hb-open-file-private.hh | 2 -- src/hb-ot-layout-common-private.hh | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) New commits: commit d6387757de2c27867d6f57c4ee7c4ef436b3a74f Author: Behdad Esfahbod Date: Wed Nov 11 17:15:03 2009 -0500 Fix sanitize diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index f8749a1..fc69c89 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -291,7 +291,7 @@ struct Lookup inline bool sanitize (SANITIZE_ARG_DEF) { TRACE_SANITIZE (); - if (!(SANITIZE_SELF/*XXXXXXXXXXXXXX*/ () && SANITIZE_THIS (subTable))) return false; + if (!(SANITIZE (lookupType) && SANITIZE (lookupFlag) && SANITIZE_THIS (subTable))) return false; if (HB_UNLIKELY (lookupFlag & LookupFlag::UseMarkFilteringSet)) { USHORT &markFilteringSet = NEXT (USHORT, subTable); commit 636f017e387d46d4083c9f9ee57647a94dc5dc6d Author: Behdad Esfahbod Date: Tue Nov 10 12:56:35 2009 -0500 Remove obsolete TODO item diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh index dda6b94..7b83813 100644 --- a/src/hb-open-file-private.hh +++ b/src/hb-open-file-private.hh @@ -147,8 +147,6 @@ struct TTCHeader TRACE_SANITIZE (); if (!SANITIZE (version)) return false; if (version.major < 1 || version.major > 2) return true; - /* TODO Maybe we shouldn't NEUTER these offsets, they may cause a full copy - * of the whole font right now. */ return table.sanitize (SANITIZE_ARG, CONST_CHARP(this), CONST_CHARP(this)); } From gzjjgod at gmail.com Tue Nov 17 23:14:51 2009 From: gzjjgod at gmail.com (Jjgod Jiang) Date: Wed, 18 Nov 2009 15:14:51 +0800 Subject: [HarfBuzz] Detecting ICU/FreeType without pkg-config? Message-ID: Hi, Currently harfbuzz-ng use pkg-config to detect whether the ICU and FreeType libraries are present. However, the official ICU code obtained from icu-project.org does not have a icu.pc file shipped (and will not generate one after compilation, if I am correct). I did notice that "./configure --help" of harfbuzz-ng mentioned ICU_FLAGS adn ICU_LIBS environment variables, but setting them didn't work for me either, configure still reported no ICU lib found. Is there any way to make harfbuzz-ng detect ICU/FreeType without using pkg-config files? Thanks. - Jiang From martin_hosken at sil.org Wed Nov 18 00:16:04 2009 From: martin_hosken at sil.org (Martin Hosken) Date: Wed, 18 Nov 2009 13:46:04 +0530 Subject: [HarfBuzz] Detecting ICU/FreeType without pkg-config? In-Reply-To: References: Message-ID: <20091118134604.4b8bf21b@sil-mh5.dallas.sil.org> Dear Jiang, > Is there any way to make harfbuzz-ng detect ICU/FreeType without using > pkg-config files? Thanks. This is what we do in grcompiler. I don't know if it is any good, but it seems to work. AC_CHECK_LIB(sicuuc, u_charType_3_6) AC_CHECK_LIB(sicuuc, u_charType_3_8) AC_CHECK_LIB(sicuuc, u_charType_3_9) AC_CHECK_LIB(sicuuc, u_charType_4_0) # Checks for header files. # need to check for icu .h files as in unicode/uchar.h AC_CHECK_HEADER(unicode/uchar.h,,) Yours, Martin From lars at kemper.freedesktop.org Wed Nov 18 04:14:30 2009 From: lars at kemper.freedesktop.org (Lars Knoll) Date: Wed, 18 Nov 2009 04:14:30 -0800 (PST) Subject: [HarfBuzz] harfbuzz: Branch 'master' Message-ID: <20091118121432.1F54810051@kemper.freedesktop.org> src/harfbuzz-indic.cpp | 10 ++-------- tests/shaping/main.cpp | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 10 deletions(-) New commits: commit b0d396aa88b3cdf8cea896bfeeba197656e1cdb1 Author: Lars Knoll Date: Wed Nov 18 13:14:31 2009 +0100 Post substitutions should apply to the whole indic syllable This fixes a bug in the rendering of Malayalam diff --git a/src/harfbuzz-indic.cpp b/src/harfbuzz-indic.cpp index 3008fca..3c9df93 100644 --- a/src/harfbuzz-indic.cpp +++ b/src/harfbuzz-indic.cpp @@ -1551,6 +1551,7 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv | PreSubstProperty | BelowSubstProperty | AboveSubstProperty + | PostSubstProperty | HalantProperty | PositioningProperties); @@ -1608,14 +1609,7 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv // pres always applies // blws always applies // abvs always applies - - // psts - // ### this looks slightly different from before, but I believe it's correct - if (reordered[len-1] != halant || base != len-2) - properties[base] &= ~PostSubstProperty; - for (i = base+1; i < len; ++i) - properties[i] &= ~PostSubstProperty; - + // psts always applies // halant always applies #ifdef INDIC_DEBUG diff --git a/tests/shaping/main.cpp b/tests/shaping/main.cpp index 12fa7c4..827ac30 100644 --- a/tests/shaping/main.cpp +++ b/tests/shaping/main.cpp @@ -686,7 +686,7 @@ void tst_QScriptEngine::bengali() void tst_QScriptEngine::gurmukhi() { { - FT_Face face = loadFace("lohit.punjabi.1.1.ttf"); + FT_Face face = loadFace("lohit_pa.ttf"); if (face) { const ShapeTable shape_table [] = { { { 0xA15, 0xA4D, 0xa39, 0x0 }, @@ -998,6 +998,36 @@ void tst_QScriptEngine::malayalam() QSKIP("couln't find AkrutiMal2Normal.ttf", SkipAll); } } + + { + FT_Face face = loadFace("Rachana.ttf"); + if (face) { + const ShapeTable shape_table [] = { + { { 0xd37, 0xd4d, 0xd1f, 0xd4d, 0xd30, 0xd40, 0x0 }, + { 0x385, 0xa3, 0x0 } }, + { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 }, + { 0x2ff, 0x0 } }, + { { 0xd33, 0xd4d, 0xd33, 0x0 }, + { 0x3f8, 0x0 } }, + { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 }, + { 0x2ff, 0x0 } }, + + { {0}, {0} } + }; + + + const ShapeTable *s = shape_table; + while (s->unicode[0]) { + QVERIFY( shaping(face, s, HB_Script_Malayalam) ); + ++s; + } + + FT_Done_Face(face); + } else { + QSKIP("couln't find Rachana.ttf", SkipAll); + } + } + } void tst_QScriptEngine::sinhala() @@ -1113,7 +1143,7 @@ void tst_QScriptEngine::nko() void tst_QScriptEngine::linearB() { { - FT_Face face = loadFace("PENUTURE.TTF"); + FT_Face face = loadFace("penuture.ttf"); if (face) { const ShapeTable shape_table [] = { { { 0xd800, 0xdc01, 0xd800, 0xdc02, 0xd800, 0xdc03, 0 }, From behdad at kemper.freedesktop.org Wed Nov 18 06:49:16 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Wed, 18 Nov 2009 06:49:16 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' Message-ID: <20091118144916.7970310051@kemper.freedesktop.org> src/hb-shape.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) New commits: commit d33f674cb793af40f1612df3660b138383f2de95 Author: Behdad Esfahbod Date: Wed Nov 18 09:47:44 2009 -0500 Add Mongolian variation selectors diff --git a/src/hb-shape.c b/src/hb-shape.c index c5e9d47..197d4a0 100644 --- a/src/hb-shape.c +++ b/src/hb-shape.c @@ -33,8 +33,9 @@ static inline hb_bool_t is_variation_selector (hb_codepoint_t unicode) { - return (unicode >= 0xFE00 && unicode <= 0xFE0F) || - (unicode >= 0xE0100 && unicode <= 0xE01EF); + return HB_UNLIKELY ((unicode >= 0x180B && unicode <= 0x180D) || /* MONGOLIAN FREE VARIATION SELECTOR ONE..THREE */ + (unicode >= 0xFE00 && unicode <= 0xFE0F) || /* VARIATION SELECTOR-1..16 */ + (unicode >= 0xE0100 && unicode <= 0xE01EF)); /* VARIATION SELECTOR-17..256 */ } static void From behdad at kemper.freedesktop.org Wed Nov 18 08:29:18 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Wed, 18 Nov 2009 08:29:18 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' Message-ID: <20091118162918.980BA10051@kemper.freedesktop.org> configure.ac | 2 ++ src/hb-ot-layout-gpos-private.hh | 4 ++-- src/hb-private.h | 13 ++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) New commits: commit c65b26acf28bd1a5b346fd8f6f28bec1f7d17a2a Author: Behdad Esfahbod Date: Wed Nov 18 11:27:33 2009 -0500 Use autoconf FLEXIBLE_ARRAY_MEMBER when available diff --git a/configure.ac b/configure.ac index 754fd47..12045cf 100644 --- a/configure.ac +++ b/configure.ac @@ -11,6 +11,8 @@ AC_PROG_LIBTOOL dnl ([1.4]) Don't remove! AC_PROG_CC AC_PROG_CXX +AC_C_FLEXIBLE_ARRAY_MEMBER + AC_CHECK_FUNCS(mprotect sysconf getpagesize) AC_CHECK_HEADERS(unistd.h sys/mman.h) diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh index f8cbe78..ad8f241 100644 --- a/src/hb-ot-layout-gpos-private.hh +++ b/src/hb-ot-layout-gpos-private.hh @@ -35,8 +35,8 @@ typedef SHORT Value; -typedef Value ValueRecord[VAR]; -ASSERT_SIZE_VAR (Value, 0, ValueRecord); +typedef Value ValueRecord[VAR0]; +ASSERT_SIZE_VAR (ValueRecord, 0, Value); struct ValueFormat : USHORT { diff --git a/src/hb-private.h b/src/hb-private.h index 845d1f0..d86c0c2 100644 --- a/src/hb-private.h +++ b/src/hb-private.h @@ -148,11 +148,18 @@ typedef int hb_mutex_t; #define ASSERT_SIZE(_type, _size) ASSERT_STATIC (sizeof (_type) == (_size)) -#define VAR 1 /* Size signifying variable-sized array */ +/* Size signifying variable-sized array */ +#ifdef FLEXIBLE_ARRAY_MEMBER +#define VAR FLEXIBLE_ARRAY_MEMBER +#else +#define VAR 1 +#endif + +#define VAR0 (VAR+0) #define ASSERT_SIZE_VAR(_type, _size, _var_type) \ - ASSERT_STATIC (sizeof (_type) == (_size) + VAR * sizeof (_var_type)) + ASSERT_STATIC (sizeof (_type) == (_size) + VAR0 * sizeof (_var_type)) #define ASSERT_SIZE_VAR2(_type, _size, _var_type1, _var_type2) \ - ASSERT_STATIC (sizeof (_type) == (_size) + VAR * sizeof (_var_type1) + VAR * sizeof (_var_type2)) + ASSERT_STATIC (sizeof (_type) == (_size) + VAR0 * sizeof (_var_type1) + VAR0 * sizeof (_var_type2)) #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) #define _HB_BOOLEAN_EXPR(expr) \ From behdad at behdad.org Wed Nov 18 11:49:09 2009 From: behdad at behdad.org (Behdad Esfahbod) Date: Wed, 18 Nov 2009 14:49:09 -0500 Subject: [HarfBuzz] Detecting ICU/FreeType without pkg-config? In-Reply-To: References: Message-ID: <4B044FB5.1060702@behdad.org> On 11/18/2009 02:14 AM, Jjgod Jiang wrote: > Hi, > > Currently harfbuzz-ng use pkg-config to detect whether the ICU and > FreeType libraries are present. However, the official ICU code obtained > from icu-project.org does not have a icu.pc file shipped (and will not > generate one after compilation, if I am correct). I did notice that > "./configure --help" of harfbuzz-ng mentioned ICU_FLAGS adn ICU_LIBS > environment variables, but setting them didn't work for me either, > configure still reported no ICU lib found. > > Is there any way to make harfbuzz-ng detect ICU/FreeType without using > pkg-config files? Thanks. Hi Jiang, The way HarfBuzz will detect external libraries is far from finished! I will go back to putting an actual configure interface in there when the library is a bit more in shape. I'll keep this in mind for ICU. For FreeType, I'm more inclined to just check for .pc. It's been years since FreeType has shipped a .pc file. Cheers, behdad > - Jiang From mpsuzuki at hiroshima-u.ac.jp Wed Nov 18 16:24:43 2009 From: mpsuzuki at hiroshima-u.ac.jp (mpsuzuki at hiroshima-u.ac.jp) Date: Thu, 19 Nov 2009 09:24:43 +0900 Subject: [HarfBuzz] Detecting ICU/FreeType without pkg-config? In-Reply-To: <4B044FB5.1060702@behdad.org> References: <4B044FB5.1060702@behdad.org> Message-ID: <20091119092443.38ee9a26.mpsuzuki@hiroshima-u.ac.jp> Hi Jiang, Also I'm interested in the reason why you want to detect FreeType without pkg-config. FreeType2 ships freetype-config, a self-standing shell script working as "pkg-config freetype2", even on the system without pkg-config. Anyway, I'm not sure if freetype-config can be a solution. Please let me know the detail why you want to detect FreeType without pkg-config. Regards, mpsuzuki On Wed, 18 Nov 2009 14:49:09 -0500 Behdad Esfahbod wrote: >On 11/18/2009 02:14 AM, Jjgod Jiang wrote: >> Hi, >> >> Currently harfbuzz-ng use pkg-config to detect whether the ICU and >> FreeType libraries are present. However, the official ICU code obtained >> from icu-project.org does not have a icu.pc file shipped (and will not >> generate one after compilation, if I am correct). I did notice that >> "./configure --help" of harfbuzz-ng mentioned ICU_FLAGS adn ICU_LIBS >> environment variables, but setting them didn't work for me either, >> configure still reported no ICU lib found. >> >> Is there any way to make harfbuzz-ng detect ICU/FreeType without using >> pkg-config files? Thanks. > >Hi Jiang, > >The way HarfBuzz will detect external libraries is far from finished! I will >go back to putting an actual configure interface in there when the library is >a bit more in shape. I'll keep this in mind for ICU. For FreeType, I'm more >inclined to just check for .pc. It's been years since FreeType has shipped a >.pc file. > >Cheers, >behdad From srl at icu-project.org Thu Nov 19 08:31:05 2009 From: srl at icu-project.org (Steven R. Loomis) Date: Thu, 19 Nov 2009 08:31:05 -0800 Subject: [HarfBuzz] Detecting ICU/FreeType without pkg-config? In-Reply-To: References: Message-ID: <4B0572C9.6040706@icu-project.org> There's a bug http://bugs.icu-project.org/trac/ticket/6981 to have ICU provide pkg-config. If someone would like to write a patch and contribute it that would be most welcome, I'm sure. -s Jjgod Jiang wrote: > Hi, > > Currently harfbuzz-ng use pkg-config to detect whether the ICU and > FreeType libraries are present. However, the official ICU code obtained > from icu-project.org does not have a icu.pc file shipped (and will not > generate one after compilation, if I am correct). I did notice that > "./configure --help" of harfbuzz-ng mentioned ICU_FLAGS adn ICU_LIBS > environment variables, but setting them didn't work for me either, > configure still reported no ICU lib found. > > Is there any way to make harfbuzz-ng detect ICU/FreeType without using > pkg-config files? Thanks. > > - Jiang > _______________________________________________ > HarfBuzz mailing list > HarfBuzz at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/harfbuzz > -- Steven R. Loomis srl at icu-project.org Technical Lead, ICU for C/C++ IBM San Jos? Globalization Center of Competency From behdad.esfahbod at gmail.com Thu Nov 19 09:33:07 2009 From: behdad.esfahbod at gmail.com (Behdad Esfahbod) Date: Thu, 19 Nov 2009 12:33:07 -0500 Subject: [HarfBuzz] Detecting ICU/FreeType without pkg-config? In-Reply-To: <4B0572C9.6040706@icu-project.org> References: <4B0572C9.6040706@icu-project.org> Message-ID: <4B058153.4080402@gmail.com> Hi Steven, This sound like something I can do. Ans while at it, do it the way I like to see it. I'll take a look. Cheers, behdad On 11/19/2009 11:31 AM, Steven R. Loomis wrote: > There's a bug http://bugs.icu-project.org/trac/ticket/6981 to have ICU > provide pkg-config. If someone would like to write a patch and > contribute it that would be most welcome, I'm sure. > > -s > > Jjgod Jiang wrote: >> Hi, >> >> Currently harfbuzz-ng use pkg-config to detect whether the ICU and >> FreeType libraries are present. However, the official ICU code obtained >> from icu-project.org does not have a icu.pc file shipped (and will not >> generate one after compilation, if I am correct). I did notice that >> "./configure --help" of harfbuzz-ng mentioned ICU_FLAGS adn ICU_LIBS >> environment variables, but setting them didn't work for me either, >> configure still reported no ICU lib found. >> >> Is there any way to make harfbuzz-ng detect ICU/FreeType without using >> pkg-config files? Thanks. >> >> - Jiang >> _______________________________________________ >> HarfBuzz mailing list >> HarfBuzz at lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/harfbuzz >> > > From neil_mayhew at sil.org Thu Nov 19 11:53:06 2009 From: neil_mayhew at sil.org (Neil Mayhew) Date: Thu, 19 Nov 2009 12:53:06 -0700 Subject: [HarfBuzz] Detecting ICU/FreeType without pkg-config? In-Reply-To: <20091119092443.38ee9a26.mpsuzuki@hiroshima-u.ac.jp> References: <4B044FB5.1060702@behdad.org> <20091119092443.38ee9a26.mpsuzuki@hiroshima-u.ac.jp> Message-ID: <4B05A222.90900@sil.org> On 09-11-18 5:24 PM mpsuzuki at hiroshima-u.ac.jp wrote: > FreeType2 ships freetype-config, a self-standing shell script working > as "pkg-config freetype2", even on the system without pkg-config. ICU does the same thing, with icu-config, so AC_CHECK_PROG(ICU, icu-config, have_icu=true, have_icu=false) would probably work as a replacement for the PKG_CHECK_MODULES that's currently there. --Neil From behdad at kemper.freedesktop.org Fri Nov 20 12:35:22 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 20 Nov 2009 12:35:22 -0800 (PST) Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' - 2 commits Message-ID: <20091120203522.4ECA310051@kemper.freedesktop.org> src/hb-open-type-private.hh | 8 ++++---- src/hb-ot-layout-common-private.hh | 2 +- src/hb-ot-layout-gdef-private.hh | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) New commits: commit 807b8aa486753474e05e09f4fcca8ac94021b97c Author: Behdad Esfahbod Date: Thu Nov 19 20:28:03 2009 -0500 Another C++ strictness fix Pango Bug 602408 - Invalid C++ code breaks compile with Sun C++ Compiler (Error: A union member cannot have a user-defined assignment operator) According to the bug: C++ Programming Language by Bjarne Stroustrup: Chapter 10.4.12 forbids explicitly using of union members with constructors, destructors or assignment operations. So we use a set() method instead of the assignment operator. Ugly, but hey, that's life. diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 63b9fe7..32f6787 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -262,7 +262,7 @@ _hb_sanitize_edit (SANITIZE_ARG_DEF, #define NEUTER(Var, Val) \ (SANITIZE_OBJ (Var) && \ _hb_sanitize_edit (SANITIZE_ARG, CONST_CHARP(&(Var)), sizeof (Var)) && \ - ((Var) = (Val), true)) + ((Var).set (Val), true)) /* Template to sanitize an object. */ @@ -349,7 +349,7 @@ struct Sanitizer #define _DEFINE_INT_TYPE1_UNALIGNED(NAME, TYPE, BIG_ENDIAN, BYTES) \ struct NAME \ { \ - inline NAME& operator = (TYPE i) { (TYPE&) v = BIG_ENDIAN (i); return *this; } \ + inline NAME& set (TYPE i) { (TYPE&) v = BIG_ENDIAN (i); return *this; } \ inline operator TYPE(void) const { return BIG_ENDIAN ((TYPE&) v); } \ inline bool operator== (NAME o) const { return (TYPE&) v == (TYPE&) o.v; } \ inline bool sanitize (SANITIZE_ARG_DEF) { \ @@ -363,7 +363,7 @@ struct Sanitizer #define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN, BYTES) \ struct NAME \ { \ - inline NAME& operator = (TYPE i) { BIG_ENDIAN##_put_unaligned(v, i); return *this; } \ + inline NAME& set (TYPE i) { BIG_ENDIAN##_put_unaligned(v, i); return *this; } \ inline operator TYPE(void) const { return BIG_ENDIAN##_get_unaligned (v); } \ inline bool operator== (NAME o) const { return BIG_ENDIAN##_cmp_unaligned (v, o.v); } \ inline bool sanitize (SANITIZE_ARG_DEF) { \ @@ -388,7 +388,7 @@ DEFINE_INT_TYPE (LONG, , 32); /* 32-bit signed integer. */ struct Tag : ULONG { inline Tag (const Tag &o) { *(ULONG*)this = (ULONG&) o; } - inline Tag (uint32_t i) { *(ULONG*)this = i; } + inline Tag (uint32_t i) { (*(ULONG*)this).set (i); } inline Tag (const char *c) { *(ULONG*)this = *(ULONG*)c; } inline bool operator== (const char *c) const { return *(ULONG*)this == *(ULONG*)c; } /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index fc69c89..9a0abe5 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -328,7 +328,7 @@ struct CoverageFormat1 if (HB_UNLIKELY (glyph_id > 0xFFFF)) return NOT_COVERED; GlyphID gid; - gid = glyph_id; + gid.set (glyph_id); // TODO: bsearch unsigned int num_glyphs = glyphArray.len; for (unsigned int i = 0; i < num_glyphs; i++) commit 8b9b866d3e495c186f0530fcf4e00ffcdc170d3f Author: Behdad Esfahbod Date: Thu Nov 19 20:27:57 2009 -0500 Fix warning diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh index 9c829e2..a047cb2 100644 --- a/src/hb-ot-layout-gdef-private.hh +++ b/src/hb-ot-layout-gdef-private.hh @@ -91,7 +91,7 @@ struct CaretValueFormat1 friend struct CaretValue; private: - inline int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id) const + inline int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id HB_GNUC_UNUSED) const { /* TODO vertical */ return context->font->x_scale * coordinate / 0x10000; From behdad at kemper.freedesktop.org Fri Nov 20 14:28:25 2009 From: behdad at kemper.freedesktop.org (Behdad Esfahbod) Date: Fri, 20 Nov 2009 14:28:25 -0800 (PST) Subject: [HarfBuzz] harfbuzz: Branch 'master' Message-ID: <20091120222825.8389010051@kemper.freedesktop.org> src/harfbuzz-shaper.cpp | 3 +++ 1 file changed, 3 insertions(+) New commits: commit 023512f09b86219d443fe3631c93b17f2199bec5 Author: Behdad Esfahbod Date: Fri Nov 20 17:26:42 2009 -0500 Bug 25199 - Variable "error" can be used without initialization. diff --git a/src/harfbuzz-shaper.cpp b/src/harfbuzz-shaper.cpp index f3ec8e1..1056f45 100644 --- a/src/harfbuzz-shaper.cpp +++ b/src/harfbuzz-shaper.cpp @@ -980,6 +980,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) HB_Stream gdefStream; gdefStream = getTableStream(font, tableFunc, TTAG_GDEF); + error = HB_Err_Not_Covered; if (!gdefStream || (error = HB_Load_GDEF_Table(gdefStream, &face->gdef))) { //DEBUG("error loading gdef table: %d", error); face->gdef = 0; @@ -987,6 +988,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) //DEBUG() << "trying to load gsub table"; stream = getTableStream(font, tableFunc, TTAG_GSUB); + error = HB_Err_Not_Covered; if (!stream || (error = HB_Load_GSUB_Table(stream, &face->gsub, face->gdef, gdefStream))) { face->gsub = 0; if (error != HB_Err_Not_Covered) { @@ -998,6 +1000,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) _hb_close_stream(stream); stream = getTableStream(font, tableFunc, TTAG_GPOS); + error = HB_Err_Not_Covered; if (!stream || (error = HB_Load_GPOS_Table(stream, &face->gpos, face->gdef, gdefStream))) { face->gpos = 0; DEBUG("error loading gpos table: %d", error); From neil_mayhew at sil.org Fri Nov 20 15:58:47 2009 From: neil_mayhew at sil.org (Neil Mayhew) Date: Fri, 20 Nov 2009 16:58:47 -0700 Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' - 2 commits In-Reply-To: <20091120203522.4ECA310051@kemper.freedesktop.org> References: <20091120203522.4ECA310051@kemper.freedesktop.org> Message-ID: <4B072D37.5080000@sil.org> A couple of comments: On 09-11-20 1:35 PM Behdad Esfahbod wrote: > (Error: A union member cannot have a user-defined assignment operator) None of the changes here directly affect any unions, only structs, so maybe the assignment operator could have been kept? If a struct contains a union, then you can't use the compiler-generated assignment operator, but you can still define your own and use something other than = to copy the union variable from the other object to this. However, maybe SANITIZE_OBJ needs to work across a range of types that includes unions, and so you need to add a method everywhere to allow uniform treatment. Even so, I didn't see any set methods being added to unions in this commit. > So we use a set() method instead of the assignment operator. FYI, the naming convention adopted in the C++ standard library is "assign", eg in std::string, so it might be a good idea to follow that. --Neil From behdad at behdad.org Fri Nov 20 16:22:22 2009 From: behdad at behdad.org (Behdad Esfahbod) Date: Fri, 20 Nov 2009 19:22:22 -0500 Subject: [HarfBuzz] harfbuzz-ng: Branch 'master' - 2 commits In-Reply-To: <4B072D37.5080000@sil.org> References: <20091120203522.4ECA310051@kemper.freedesktop.org> <4B072D37.5080000@sil.org> Message-ID: <4B0732BE.8020402@behdad.org> On 11/20/2009 06:58 PM, Neil Mayhew wrote: > A couple of comments: > > On 09-11-20 1:35 PM Behdad Esfahbod wrote: >> (Error: A union member cannot have a user-defined assignment operator) > None of the changes here directly affect any unions, only structs, so > maybe the assignment operator could have been kept? If a struct contains > a union, then you can't use the compiler-generated assignment operator, > but you can still define your own and use something other than = to copy > the union variable from the other object to this. The problem occurs in cases like: union { USHORT format; /* Format identifier */ CoverageFormat1 format1[VAR]; CoverageFormat2 format2[VAR]; } u; where previously USHORT had an overloaded assignment operator. I could "fix" this by wrapping USHORT into a separate Format struct. One way or the other. > However, maybe SANITIZE_OBJ needs to work across a range of types that > includes unions, and so you need to add a method everywhere to allow > uniform treatment. Even so, I didn't see any set methods being added to > unions in this commit. The only place in the SANITIZE code that we actually assign anything is in NEUTER(). And we only neuter offsets, which are int types and inherit that set() method. >> So we use a set() method instead of the assignment operator. > FYI, the naming convention adopted in the C++ standard library is > "assign", eg in std::string, so it might be a good idea to follow that. Our C++ usage is so limited and different from most "standards" that I don't see much point really :). Cheers, behdad > --Neil