/* State 0: prev was U, not willing to join. */
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
/* State 1: prev was R or ISOL/ALAPH, not willing to join. */
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
/* State 2: prev was D/L in ISOL form, willing to join. */
{ {NONE,NONE,0}, {NONE,ISOL,2}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
/* State 3: prev was D in FINA form, willing to join. */
{ {NONE,NONE,0}, {NONE,ISOL,2}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
/* State 4: prev was FINA ALAPH, not willing to join. */
{ {NONE,NONE,0}, {NONE,ISOL,2}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
/* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
{ {NONE,NONE,0}, {NONE,ISOL,2}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
/* State 6: prev was DALATH/RISH, not willing to join. */
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
};
/* We apply features according to the Arabic spec, with pauses *inbetweenmost. * *Thepausebetweeninit/medi/...andrligisrequired.Seeeg: *https://bugzilla.mozilla.org/show_bug.cgi?id=644184 * *Thepausesbetweeninit/medi/...themselvesarenotnecessarily *neededasonlyoneofthosefeaturesisappliedtoanycharacter. *Theonlydifferenceitmakesiswhenfontshavecontextual *substitutions.Wenowfollowtheorderofthespec,whichmakes *forbetterexperienceifthat'swhatUniscribeisdoing. * *AtleastforArabic,lookslikeUniscribehasapausebetween *rligandcalt.OtherwisetheIranNastaliq'sALLAHligaturewon't *work.However,testingshowsthatrligandcaltareapplied *togetherforMongolianinUniscribe.Assuch,weonlyadda *pauseforArabic,nototherscripts.
*/
/* Normally, Unicode says a ZWNJ means "don't ligate". In Arabic script *however,itsaysaZWJshouldalsomean"don'tligate".Sowerun
* the main ligating features as MANUAL_ZWJ. */
/* The spec includes 'cswh'. Earlier versions of Windows *usedtoenablethisbydefault,buttestingsuggests *thatWindows8andlaterdonotenableitbydefault, *andspecnowsays'Offbydefault'. *Wedisabledthisinae23c24c32. *NotethatIranNastaliqusesthisfeatureextensively *tofixupbrokenglyphsequences.Ohwell...
* Test case: U+0643,U+0640,U+0631. */ //map->enable_feature (HB_TAG('c','s','w','h'), F_MANUAL_ZWJ);
map->enable_feature (HB_TAG('m','s','e','t'), F_MANUAL_ZWJ);
}
#include"hb-ot-shaper-arabic-fallback.hh"
struct arabic_shape_plan_t
{ /* The "+ 1" in the next array is to accommodate for the "NONE" command, *whichisnotanOpenTypefeature,butthissimplifiesthecodebynot *havingtodoa"if(...<NONE)..."andjustrelyonthefactthat
* mask_array[NONE] == 0. */
hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1];
if (entry->prev_action != NONE && prev != UINT_MAX)
{
info[prev].arabic_shaping_action() = entry->prev_action;
buffer->safe_to_insert_tatweel (prev, i + 1);
} else
{ if (prev == UINT_MAX)
{ if (this_type >= JOINING_TYPE_R)
buffer->unsafe_to_concat_from_outbuffer (0, i + 1);
} else
{ if (this_type >= JOINING_TYPE_R ||
(2 <= state && state <= 5) /* States that have a possible prev_action. */)
buffer->unsafe_to_concat (prev, i + 1);
}
}
retry:
arabic_fallback_plan_t *fallback_plan = arabic_plan->fallback_plan; if (unlikely (!fallback_plan))
{ /* This sucks. We need a font to build the fallback plan... */
fallback_plan = arabic_fallback_plan_create (plan, font); if (unlikely (!arabic_plan->fallback_plan.cmpexch (nullptr, fallback_plan)))
{
arabic_fallback_plan_destroy (fallback_plan); goto retry;
}
}
/* 'stch' feature was just applied. Look for anything that multiplied, *andrecorditforstchtreatmentlater.Notethatrtlm,frac,etc *areappliedbeforestch,butweassumethattheydidn'tresultin
* anything multiplying into 5 pieces, so it's safe-ish... */
/* We do a two pass implementation: *Firstpasscalculatestheexactnumberofextraglyphsweneed, *Wethenenlargebuffertohavethatmuchroom, *Secondpassappliesthestretch,copyingthingstotheendofbuffer.
*/
int sign = font->x_scale < 0 ? -1 : +1; unsignedint extra_glyphs_needed = 0; // Set during MEASURE, used during CUT enum { MEASURE, CUT } /* step_t */;
hb_position_t w_total = 0; // Total to be filled
hb_position_t w_fixed = 0; // Sum of fixed tiles
hb_position_t w_repeating = 0; // Sum of repeating tiles int n_fixed = 0; int n_repeating = 0;
/* See if we can improve the fit by adding an extra repeat and squeezing them together a bit. */
hb_position_t extra_repeat_overlap = 0;
int64_t shortfall = w_remaining_signed - w_repeating_signed * (n_copies + 1); if (shortfall > 0 && n_repeating > 0)
{
++n_copies;
int64_t excess = (n_copies + 1) * w_repeating_signed - w_remaining_signed; if (excess > 0)
{
extra_repeat_overlap = excess / (n_copies * n_repeating);
w_remaining = 0;
}
}
staticconst hb_codepoint_t
modifier_combining_marks[] =
{ 0x0654u, /* ARABIC HAMZA ABOVE */ 0x0655u, /* ARABIC HAMZA BELOW */ 0x0658u, /* ARABIC MARK NOON GHUNNA */ 0x06DCu, /* ARABIC SMALL HIGH SEEN */ 0x06E3u, /* ARABIC SMALL LOW SEEN */ 0x06E7u, /* ARABIC SMALL HIGH YEH */ 0x06E8u, /* ARABIC SMALL HIGH NOON */ 0x08CAu, /* ARABIC SMALL HIGH FARSI YEH */ 0x08CBu, /* ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW */ 0x08CDu, /* ARABIC SMALL HIGH ZAH */ 0x08CEu, /* ARABIC LARGE ROUND DOT ABOVE */ 0x08CFu, /* ARABIC LARGE ROUND DOT BELOW */ 0x08D3u, /* ARABIC SMALL LOW WAW */ 0x08F3u, /* ARABIC SMALL HIGH WAW */
};
staticinlinebool
info_is_mcm (const hb_glyph_info_t &info)
{
hb_codepoint_t u = info.codepoint; for (unsignedint i = 0; i < ARRAY_LENGTH (modifier_combining_marks); i++) if (u == modifier_combining_marks[i]) returntrue; returnfalse;
}
DEBUG_MSG (ARABIC, buffer, "Reordering marks from %u to %u", start, end);
unsignedint i = start; for (unsignedint cc = 220; cc <= 230; cc += 10)
{
DEBUG_MSG (ARABIC, buffer, "Looking for %u's starting at %u", cc, i); while (i < end && info_cc(info[i]) < cc)
i++;
DEBUG_MSG (ARABIC, buffer, "Looking for %u's stopped at %u", cc, i);
if (i == end) break;
if (info_cc(info[i]) > cc) continue;
unsignedint j = i; while (j < end && info_cc(info[j]) == cc && info_is_mcm (info[j]))
j++;
if (i == j) continue;
DEBUG_MSG (ARABIC, buffer, "Found %u's from %u to %u", cc, i, j);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.